名称解析
M:model 数据模型和逻辑操作,即我们常用的网络交互。
V:view 视图层,即我们通常所说的activity或fragment。
P:present 代理层。代理完成model与view所有的交互。
关于MVP的实现代码,每个人的实现不一定完全相同,但是大体思路基本不变。
这里我把Model层交给retrofit框架去处理了,为了简化代码,并没有对其进一步的封装。
登录模块
下面以我们平时最简单最熟悉的登录模块为例。
代码结构图:
基本思路
view层: 输入用户名和密码
present层:处理登录操作
model层: retrofit处理登录请求数据,交给present通知view
view层并不直接与model层发生关系。通过代理present来处理
场景理解
客户进入餐厅,叫服务员点餐,服务员收到点餐的指令,点完餐后,把菜单交给厨师去处理,厨师做好菜,交给服务员。
服务员收到菜做好后,端给客户享用。
客户相当于view
服务员相当于present
厨师相当于model
理解了这种思路,下面就代码的具体实现来做一下分析
View
接口类:IView
登录成功回调方法:onLogin(String result)
登录失败回调方法:onFailure()
具体代码
public interface IView { void onLogin(String result); void onFailure(); }
代码说明
我们定义的IView,通过LoginActivity类来implements。
LoginActivity通过代理类IPresenter,处理的登录操作。
通过onLogin(String result) 和 onFailure() 来刷新或处理界面元素。
实现类
下面是LoginActivity类的代码:
public class LoginActivity extends BaseActivity implements IView {
private IPresenter iPresenter;
@Override
protected void initView(Bundle savedInstanceState) {
//view初始化处理
iPresenter = new IPresenter(this);
}
@Override
public void onClick(View v) {
case R.id.textLogin:
// 登录处理
showLoadingDialog();
iPresenter.onLogin(json);
break;
default:
break;
}
}
@Override
public void onLogin(String data) {
dismissLoadingDialog();
//正常返回 逻辑处理
}
@Override
public void onFailure() {
dismissLoadingDialog();
}
@Override
public void onBackPressed() {
if (iPresenter != null) {
iPresenter.onCancel();
}
super.onBackPressed();
}
}
Present
上面提到LoginActivity类的登录操作交给IPresenter来处理。 IPresenter处理登录操作,将登录异步请求,交由retrofit处理, 这里的retrofit相当于model层,处理完后,交由IPresenter来处理结果返回给view端。 具体实现代码 public class IPresenter { private IView view; private Call<ResponseData<ReturnData>> call; public IPresenter(IView view){ this.view = view; } public void onLogin(String json){ call = App.getInstance().getService().accountService(json); call.enqueue(new AccountLoginCallBack(view)); } public void onCancel() { if (call != null && call.isExecuted()) { call.cancel(); } } }
当然IPresenter也可写成接口类,更易扩展逻辑的实现。
这里省去了这个环节,重点在解释MVP的实现思路。
MVP模式的过程流程如下所示:
总结
通过上面的代码MVP的有点显而易见:
1、减少Actitity中的代码量。业务实现更清楚
2、模型与视图完全分离,我们可以修改视图而不影响模型
3、增加复用性,任何用到登录的地方都可以用极少的代码,不改变业务逻辑的复用。
4、我们可以脱离用户接口来测试这些逻辑(单元测试)
这样不必等待后台服务接口开发完成才能调通整个逻辑。提高了开发效率。