不管是MVC、还是MVP,它们的设计目的都是为了达到编码的最高境界:高内聚、低耦合、高复用、易测试和好维护。
那怎么样才能达到以上的目标?1.任务拆分,每个部分各自负责什么2.如何组合在一起。架构关键的两部:拆分和组合。
刚做项目时,所有的代码,如数据的访问和处理,界面展示都写在Activity中,写的时候很舒服,各种堆,导致Activity的代码一言不合就上千行(mmp),就会出现各种问题。
- 当业务越来越复杂时,需要修改的时候,牵一发而动全身,修改一个地方,导致其他的地方也受到了影响,导致bug出现。
- 时间一长,别说别人,自己都TM看不懂了。
- 当需要做一个功能时,发现代码无法复用,明明一样的逻辑也只能ctrl+c和ctrl+v了,如果以后需要修改,就不谈了(都是泪),效率低和加班是有原因的。
要换的不是架构,而是思维方式
如何在解决问题的时候把问题合理的拆分,又如何将拆分的零件合理的组装成解决问题的工具。
现在谈一下我个人对MVP模式的理解。
mvp模式.PNG
拆分
- View 负责界面显示
- Model 负责定义数据类型
- Presenter 负责Model和View之间的逻辑处理
组合
如图Presenter把View和Model分离了,这里,我们把View当成Activity,Presenter需要持有Activity,Presenter肯定不能直接持有Activity,因为每个Activity的方法不一样,我们可以声明一个接口,但有不同的实现。我们把各自不同的实现方法理解成契约。这样Presenter持有Activity的引用了。
当用户操作时,来触发Presenter,调用对应的方法(例如:请求网络),网络请求成功后,在Presenter返回数据Model,此时调用View的方法,在对应的Activity中实现此方法,进行界面上数据的展示。
总结一下,再次看一下上面的MVP模式的图片,Model不主动和Presenter联系,被动的等着Presenter来调用,View和Presenter是两个方向,Presenter中View调用方法,实现方法时已经获得Model。
用MVP实现了一个简单的demo,便于理解其中的关系。
![](https://img.haomeiwen.com/i2146512/2c9470c126c4b9a6.gif)
- BaseContract
在View中我们有一些常用的方法,例如loading、dialog不用每个都写,所以弄成一个基类。
public interface BaseContract {
interface Presenter {
void start();
void destroy();
}
interface View<T extends Presenter> {
void showError(@StringRes int str);
void showLoading();
void setPresenter(T presenter);
}
interface RecyclerView<ViewModel, T extends Presenter> extends View<T> {
RecyclerAdapter<ViewModel> getRecyclerAdapter();
}
}
- BasePresenter
public class BasePresenter<T extends BaseContract.View> implements BaseContract.Presenter {
private T mView;
public BasePresenter(T view) {
setView(view);
}
private void setView(T view) {
this.mView = view;
this.mView.setPresenter(this);
}
@Override
public void start() {
T view = mView;
if (view != null) {
view.showLoading();
}
}
@Override
public void destroy() {
T view = mView;
mView = null;
if (view != null) {
mView.setPresenter(null);
}
}
protected final T getView() {
return mView;
}
}
- 实现类
public interface NewsContract {
interface Presenter extends BaseContract.Presenter{
}
interface View extends BaseContract.RecyclerView<NewsModel.ResultBean.ListBean,Presenter>{
void onSearchDone(List<NewsModel.ResultBean.ListBean> model);
}
//只是一个显示列表,没有什么操作,在基类中已经实现
}
public class NewsPresenter extends BaseRecyclerPresenter<NewsModel.ResultBean.ListBean, NewsContract.View>
implements DataSource.Callback<List<NewsModel.ResultBean.ListBean>>, NewsContract.Presenter {
private List<NewsModel.ResultBean.ListBean> mNewsModels;
private NewsContract.View mView;
private int mStrRes;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
mView.onSearchDone(mNewsModels);
break;
case 1:
mView.showError(mStrRes);
break;
default:
break;
}
}
};
public NewsPresenter(NewsContract.View view) {
super(view);
}
@Override
public void start() {
super.start();
//Todo 请求网络 延迟请求 看Loading效果
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
NewsHelper.refresh(NewsPresenter.this);
}
}, 2000);
}
@Override
public void onDataLoad(List<NewsModel.ResultBean.ListBean> newsModels) {
NewsContract.View view = getView();
if (view == null) {
return;
}
mNewsModels = newsModels;
mView = view;
mHandler.sendEmptyMessage(0);
}
@Override
public void onDataNotAvailable(@StringRes int strRes) {
NewsContract.View view = getView();
if (view == null) {
return;
}
mView = view;
mHandler.sendEmptyMessage(1);
mStrRes = strRes;
}
}
网友评论