引言
如果用常見于web開發(fā)中的MVC模式來開發(fā)Android,由于Controller控制器的責(zé)任常常會(huì)落在Activity身上,導(dǎo)致Activity變得臃腫,對(duì)UI層和業(yè)務(wù)層的單元測(cè)試有很大的不便。所以我們來看看MVP模式。
為什么使用MVP
看一下如果不用MVP模式,Android項(xiàng)目會(huì)如何:

Android_mvp_view_data.jpg
你會(huì)發(fā)現(xiàn)View和Model層交互的很亂,這就導(dǎo)致數(shù)據(jù)層和UI層的單元測(cè)試很麻煩。
我們看一下MVP模式:

android_mvp.jpg
你會(huì)發(fā)現(xiàn)Android項(xiàng)目結(jié)構(gòu)非常的清楚,這在開發(fā)中勢(shì)必會(huì)事半功倍。、
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.
看下項(xiàng)目結(jié)構(gòu):

google_mvp_basic.jpg
結(jié)構(gòu)說明:
| 目錄 | 說明 | 常用工具 |
|---|---|---|
| androidTest | UI測(cè)試 | Espresso/automator |
| androidTestMock | UI測(cè)試mock數(shù)據(jù)支持 | Mockito |
| src | 實(shí)現(xiàn)代碼 | |
| mock | 業(yè)務(wù)層單元擦拭mock數(shù)據(jù)支持 | Mockito |
| test | 業(yè)務(wù)層單元測(cè)試 | Junit |
src下的tasks代碼
BaseView->抽象出View,提取公共行為
public interface BaseView<T> {
/**
* 使用fragment作為view時(shí),將activity中的presenter傳遞 給fragment
* @param presenter
*/
void setPresenter(T presenter);
}
BasePresenter->抽象出Presenter
public interface BasePresenter {
/**
* 頁面初始化的時(shí)候做的事情,根據(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
從上面的代碼你會(huì)看到Fragment 即View和Presenter的創(chuàng)建,從中可以看出Activity的職責(zé):
- 負(fù)責(zé)建立View和Presenter的交互關(guān)系。
Model僅和Presenter建立關(guān)系
你會(huì)發(fā)現(xiàn)只有Presenter調(diào)用Model層,而View和Model毫無關(guān)系。
總結(jié)
- MVP模式將UI代碼與業(yè)務(wù)層進(jìn)行解耦,將UI又與Model層進(jìn)行分離,增強(qiáng)了可測(cè)試性。
- 多實(shí)踐,多揣摩。