之前一直用的MVC模式,但是業(yè)務(wù)邏輯稍微復(fù)雜懂版,MVC的缺點就暴露了:View和modle雜糅在一起,有時候為了代碼書寫方便兼都,把所有邏輯都寫在Activity里面漂羊,經(jīng)常導(dǎo)致Activity代碼超過1000行,雖然多少行代碼并沒有什么實際意義侣背,但耦合度高總不是我們想要的白华,于是就想嘗試一下MVP模式(雖然大部分人都已經(jīng)用上了),之前的想法是先把一個最復(fù)雜的模塊替換為MVP模式試用一段時間贩耐,于是花了3天時間把這個模塊從MVC替換為MVP弧腥,自己去查MVP資料總感覺不夠理解,真正動手做了一遍發(fā)現(xiàn)理解難度大大降低潮太,并且嘗試到了MVP的甜頭管搪,最后產(chǎn)品經(jīng)理更改登陸模塊需求的時候果斷把登陸模塊也替換為MVP模式(一發(fā)不可收拾),下面記錄下我對MVP模式的理解铡买。
MVP的思想是一樣的更鲁,但是寫法每個人都不一樣,我參考的例子是: https://github.com/antoniolg/androidmvp
MVP的優(yōu)勢:UI奇钞、邏輯分離(類似于前端的前后端分離)澡为,邏輯非常清晰
MVP的劣勢:上手有難度,代碼量比較大
對于一個想長期維護的項目來說景埃,優(yōu)勢的影響遠遠大于劣勢的影響媒至,所以果斷上手吧顶别。
本博客記錄的MVP模式的結(jié)構(gòu)如下圖:
從結(jié)構(gòu)圖可以看到,與Activity交互的只有View和Presenter,所有邏輯交互都放在presenter里面處理拒啰。
舉個例子:有個顯示列表的界面驯绎,可以通過下拉刷新請求數(shù)據(jù)并刷新view。
1谋旦、定義Listener : GetDataListener
public interface GetDataListener{
void onGetDataSuccess(List<Data> data);
void onGetDataFail();
}
2条篷、定義Interactor:GetDataInteractor
public interface GetDataInteractor{
void getData();
}
3、實現(xiàn)Interactor:GetDataInteractorImpl
public interface GetDataInteractorImpl implements GetDataInteractor{
@Override
public void getData(Params params, GetDataListener listener){
request(Params params){
@Override
public void onRequestSuccess(List<Data> data){
listener.onGetDataSuccess(data);
}
@Override
public void onRequestFail(){
listener.onGetDataFail();
}
}
});
}
4蛤织、定義View
public interface TestView{
void refreshData(List<Data> dataList);
}
5、定義Presenter
public interface Presenter{
void requestData();
}
6鸿染、實現(xiàn)Presenter:PresenterImpl
public class PresenterImpl implements Presenter,GetDataListener{
TestView mView;
GetDataInteractor mInteractor;
List<Data> mDataList;
public PresenterImpl(TestView view){
this.mView = view;
mInteractor = new GetDataInteractorImpl();
}
@Override
public void requestData(){
mInteractor.getData(params, this);
}
@Override
public void onGetDataSuccess(List<Data> dataList){
mDataList = dataList;//mDataList.addAll(dataList);
mView.refreshData(mDataList);
}
@Override
public void onGetDataFail(){
//do something....
}
}
7指蚜、定義Activity
public class TestActivity extends Activity implements TestView{
ListView mListView;
Presenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
init();
}
private void init(){
mListView = (ListView)findViewById(R.id.listview);
mPresenter = new PresenterImpl(this);
mListView.setOnItemClickListener(new OnItemClickListener() {
//假如點擊一次就刷新
mPresenter.requestData();
});
}
public void refreshData(List<Data> dataList){
mListView.otifyDataSetChange();
}
}
如此7步,一個簡單的mvp模式的例子就完成了涨椒,可以看到摊鸡,數(shù)據(jù)List<Data>保存在PresenterImpl里面,Activity只負責顯示蚕冬,Activity不負責任何邏輯(非常簡單的邏輯可以寫在Activity里面)免猾。
如果后臺想改接口,換成另一個接口來請求數(shù)據(jù)囤热,非常簡單猎提,在Interactor里面改就行了,如果基本數(shù)據(jù)不變旁蔼,照常返回的數(shù)據(jù)還是Data锨苏,則其他地方根本不用動,如果Data結(jié)構(gòu)變化棺聊,只需要改Interactor和Presenter就行了伞租,Activity和View不用動。
如果產(chǎn)品經(jīng)理改需求限佩,需要在請求的時候加上Loading效果葵诈,同樣非常簡單,在View增加一個showLoading和hideLoading接口祟同,然后在Activity實現(xiàn)作喘,這樣在Presenter里面任何時候想調(diào)用就可以隨時mView.showLoading,完全不用管showLoading具體怎么實現(xiàn)耐亏。
從以上例子可知徊都,UI和邏輯的分離帶給我們的好處有多大,整個模塊邏輯非常清晰广辰,更改需求也非常簡單暇矫,趕快上手吧主之。
代碼量確實有比較大的增加,可以考慮開發(fā)一個android studio插件自動生成presenter李根、interactor槽奕、Listener代碼。