android mvp模式有什么弊端
才開始學習使用MVP時,看到大家說了很多MVP的優點,代碼復用,條理清晰等等。不過我改下來發現,MVP在我看來,最大的優點還是代碼解耦,邏輯清晰,至于代碼復用,暫時沒有感覺很好用,除非是界面和邏輯基本一樣的,不然想要復用,其實不太現實。
MVP的優點很明顯,缺點其實也很明顯,明顯項目會多出許多類,增加了項目的復雜程度,而且像某些邏輯及其簡單,事件較少的界面,使用MVP實際上反而是累贅,明明用MVC也就幾十行代碼的事,改成MVP多了好多個類,反而感覺不劃算,改需求時又要翻閱好多個類。因此,我建議大家,如果你的某個界面極其簡單,其實就不要用MVP了,MVP是邏輯越復雜,優勢越明顯,邏輯簡單時,反而不如MVC好用,希望大家不要為了用MVP而用MVP。
下面來談談文章主題,MVP的優化問題,最開始采用網上大家的寫法,發現代碼的復用性不好,有些邏輯類似的代碼,基本上每個presenter 和model都要重新寫,于是想到使用Base類的方法,把某些共有的方法抽離以達到代碼的復用性,類似于BaseActivity。
舉個例子比如網絡請求,在MVC中通常是把網絡請求封裝在BaseActivity中,不過既然是MVP,網絡請求自然應該封裝在Model里面啦
public abstract class BaseActivityModel implements IPublicModel {
//網絡連接模式,當一個頁面含有多個網絡請求時,通過傳入不同的模式,選擇相應的加載參數
public static final int MODE_ONE=1;
public static final int MODE_TWO=2;
public static final int MODE_THREE=3;
//網絡連接工具接口類
protected InternetConnect mConnect;
/**
* @param mode 請求模式
* @param intent 上個頁面傳遞過來的intent
* @param i 請求回調
* @param parameter 請求的一些參數
*/
@Override
public void requestData (int mode, Intent intent, JsonI i, String.。。 parameter) {
HashMap《String, String》 map = new HashMap《》();
JsonBean.Payload payload=new JsonBean.Payload();
mConnect.loadParameter(intent,mode,payload,map,parameter);//加載參數,由子類實現
map.put(“payload”, VolleyConnect.getGson().toJson(payload));
VolleyConnect.getInVolleyConnect().getServiceMsg( map,i);//封裝Volley,傳入參數以及回調接口
}
/**
* 設置網絡請求
*/
@Override
public void setMConnect (InternetConnect mConnect) {
this.mConnect=mConnect;
}
}
同樣的共有的方法和字段抽象出presenter的基類
public abstract class BaseActivityPresenter《T extends IPublicView, E extends IPublicModel》 implements IPublicPresenter {
protected T view;
protected E model;
protected RequestResult mRequestResult;
protected Handler mHandler;
public BaseActivityPresenter (T view) {
this.view = view;
Type type = getClass().getGenericSuperclass();//使用反射實例化Model
Type trueType = ((ParameterizedType) type).getActualTypeArguments()[1];
try {
this.model = ((Class《E》) trueType).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
new TimeCount(200, 50, new ITimeCount() {
@Override
public void isRuning (long millisUntilFinished) {
}
@Override
public void isFinish () {
init();//加載子類方法,延時200毫秒加載
}
}).start();
}
/*
設置網絡請求回調
*/
public void setRequestResult (RequestResult requestResult) {
mRequestResult = requestResult;
}
/*
獲取view的handler,需要傳入一個回調接口
*/
public void setHandler (IHandler handlerI) {
mHandler = view.exposeHandler(handlerI);
}
@Override
public void requestData (final int mode, String.。。 parameter) {
view.setLoading(true);
model.requestData(mode, view.exposeIntent(), new JsonI() {
@Override
public void notice (JsonBean bean) {
// if (bean.getStatus().equals(“0”)) {
// mRequestResult.requestDataSuccess(mode,bean);
// }else{
// mRequestResult.requestDataFail(mode,bean);
// }
view.setLoading(false);
}
@Override
public void notice (int error) {
view.showError(error);
}
}, parameter);
}
}
這樣我們就可以更加簡單方便的使用MVP模式了,下面是使用示例
public class LoginPresenter extends BaseActivityPresenter《ILoginView,LoginModel》 implements ILoginPresenter, RequestResult {
public LoginPresenter (ILoginView view) {
super(view);
}
@Override
public void init () {
setRequestResult(this);
}
@Override
public void requestDataSuccess (int mode, JsonBean bean) {
}
@Override
public void requestDataFail (int mode, JsonBean bean) {
}
}
可以看到,LoginPresenter不再需要去寫model字段和網絡請求邏輯,通過泛型,可以自動創建model,而網絡請求,僅僅需要設置對應的回調就可以噠。
總結,這樣做進一步降低了代碼耦合,方便以后代碼維護,而且整個MVP感覺更加簡單。
評論