引言
如果用常見于web開發(fā)中的MVC模式來開發(fā)Android,由于Controller控制器的責(zé)任常常會落在Activity身上,導(dǎo)致Activity變得臃腫,對UI層和業(yè)務(wù)層的單元測試有很大的不便戳鹅。所以我們來看看MVP模式。
為什么使用MVP
看一下如果不用MVP模式,Android項目會如何:
Android_mvp_view_data.jpg
你會發(fā)現(xiàn)View和Model層交互的很亂,這就導(dǎo)致數(shù)據(jù)層和UI層的單元測試很麻煩昏兆。
我們看一下MVP模式:
android_mvp.jpg
你會發(fā)現(xiàn)Android項目結(jié)構(gòu)非常的清楚,這在開發(fā)中勢必會事半功倍枫虏。、
MVP職責(zé)
- View:負(fù)責(zé)繪制UI元素,用戶交互
- Presenter:用于View和Model交互,處理業(yè)務(wù)邏輯爬虱。
- Model:負(fù)責(zé)數(shù)據(jù)的提供
Google 官方MVP示例分析
下載:示例
我們分析的是todo-mvp/ - Basic Model-View-Presenter architecture.
看下項目結(jié)構(gòu):
google_mvp_basic.jpg
結(jié)構(gòu)說明:
目錄 | 說明 | 常用工具 |
---|---|---|
androidTest | UI測試 | Espresso/automator |
androidTestMock | UI測試mock數(shù)據(jù)支持 | Mockito |
src | 實現(xiàn)代碼 | |
mock | 業(yè)務(wù)層單元擦拭mock數(shù)據(jù)支持 | Mockito |
test | 業(yè)務(wù)層單元測試 | Junit |
src下的tasks代碼
BaseView->抽象出View,提取公共行為
public interface BaseView<T> {
/**
* 使用fragment作為view時隶债,將activity中的presenter傳遞 給fragment
* @param presenter
*/
void setPresenter(T presenter);
}
BasePresenter->抽象出Presenter
public interface BasePresenter {
/**
* 頁面初始化的時候做的事情,根據(jù)業(yè)務(wù)決定是否需要
*/
void start();//加載數(shù)據(jù)跑筝,一般在View的onResume()中執(zhí)行死讹。
}
契約類:TasksContract->用于View和Presenter交互的管理
public interface TasksContract {
interface View extends BaseView<Presenter> {
void setLoadingIndicator(boolean active);
void showTasks(List<Task> tasks);
...
}
interface Presenter extends BasePresenter {
void result(int requestCode, int resultCode);
void loadTasks(boolean forceUpdate);
...
}
}
Activity在MVP中作用
mvp_activity.jpg
從上面的代碼你會看到Fragment 即View和Presenter的創(chuàng)建,從中可以看出Activity的職責(zé):
- 負(fù)責(zé)建立View和Presenter的交互關(guān)系。
Model僅和Presenter建立關(guān)系
你會發(fā)現(xiàn)只有Presenter調(diào)用Model層,而View和Model毫無關(guān)系曲梗。
總結(jié)
- MVP模式將UI代碼與業(yè)務(wù)層進(jìn)行解耦,將UI又與Model層進(jìn)行分離,增強(qiáng)了可測試性赞警。
- 多實踐,多揣摩妓忍。