共计 2406 个字符,预计需要花费 7 分钟才能阅读完成。
MVP 简介
MVP 全称:Model-View-Presenter;MVP 是从经典的模式 MVC 演变而来,它们的基本思想有相通的地方:Controller/Presenter 负责逻辑的处理,Model 提供数据,View 负责显示。
对于 MVC 不了解的朋友可以查此文:
Android 进阶之路 (1)- 详解 MVC
Android 中的 MVP:
-
M 层:适合做一些业务逻辑处理,比如数据库存取操作,网络操作,复杂的算法,耗时的任务等都在 model 层处理。和 MVC 类似
- V 层:对应的 Activity,负责 xml 绘制与页面交互
- P 层:负责 View 与 Model 之间的交互
为什么要用 MVP
我们先想想上篇文章,我们讲到为什么要用 MVC,当时我们总结了几点:
- 代码复用
- 耦合性低
- 方便维护的高等
然而我们在写 MVC 项目时候,也发现了一些问题:
1. 对于 Android 中的 Activity 或者 Fragment,我们不能很清晰的区分它是 View 还是 Controller,既有交互又有页面绘制,这就导致了 activity 和 fragment 很“庞大”
2.View 与 Model 确实是分离的,但是关联性太强,这就导致 activity 与 model 的联系强,这样我们只要改一点点代码,model、view、activity 都会变,维护成本太高,View 与 Model 之前的耦合性太高。
而 MVP 最大的改变就是 View 与 Model 实现完全隔离。View 把操作意图给 P 层,P 收到后,会调用 Model 层来实现具体的逻辑,逻辑实现后会再通知给 P,P 再通过 View 的接口回调给 View。即便 V 和 M 更改了,也不会有影响,耦合性低。
MVP DEMO
以登录模块为例,来实现 MVP
1. 定义 View 接口 - ILoginView
/**
* 获取 view 层的 dialog
*
* @return retuen
*/
Dialog getLoadDialog();
/***
* 关闭 view 层的 dialog
*/
void cancelLoadDialog();
/**
* 获取手机号参数
*
* @return username
*/
String getPhone();
/**
* 获取密码
*
* @return password
*/
String getCode();
/**
* 弹出消息
*
* @param msg msg
*/
void showMsg(String msg);
View 接口大家都明白吧?就是你要告诉给 P 的意图。activity 实现此接口。并调用 P 的方法:
@Override
public void cancelLoadDialog() {if (dialog!=null&&dialog.isShowing()){dialog.dismiss();
}
}
@Override
public String getPhone() {return edPhone.getText().toString();}
@Override
public String getCode() {return edCode.getText().toString();}
@Override
public void showMsg(String msg) {Toast.makeText(getApplicationContext(),msg,Toast.LENGTH_SHORT).show();}
mPresenter.login();
2. 定义 Model 与 ModelImpl
Model:
public interface ILoginModel {void login(String phone, String code, OnLoadDatasListener<CurrencyBean.DataBean> onLoadDatasListener);
}
ModelImpl:
@Override
public void login(String phone, String code, final OnLoadDatasListener<CurrencyBean.DataBean> onLoadDatasListener) {// 填写具体的操作逻辑与 onLoadDatasListener 回调}
model 实现类逻辑处理完成之后会通知给 P,定义 P:
/**
* 登陆
*/
public void login() {if (mView == null) return;
if (TextUtils.isEmpty(mView.getPhone()) || TextUtils.isEmpty(mView.getCode())) {mView.showMsg("手机号或密码不能为空");
return;
}
mView.getLoadDialog().show();
loginModel.login(mView.getPhone(), mView.getCode(), new OnLoadDatasListener<CurrencyBean.DataBean>() {
@Override
public void onSuccess(CurrencyBean.DataBean dataBean) {Gson gson=new Gson();
mView.cancelLoadDialog();
Log.e("qzs----",gson.toJson(dataBean)+"");
mView.loginSuccess();}
@Override
public void onFailure(String error) {mView.cancelLoadDialog();mView.loginFail();}
});
}
P 通过 View 接口返回给 View
另外 MVP 也是有缺点的:
- 增加代码的复杂度
- 实现难度增加
- 如果某特定视图的渲染很多(activity),就会造成 Presenter 与该视图联系过于紧密,一旦该视图需要变更,那么 Presenter 也需要变更了,不能如预期的那样降低耦合度和增加复用性。
大家可以关注我的微信公众号:「秦子帅」一个有质量、有态度的公众号!