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感觉更加简单。
评论
查看更多