解读Android官方MVP项目单元测试
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0425/4178.html
MVP的概念
在MVP模式里通常包含4个要素:
(1)View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
(2)View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
(3)Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
(4)Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
MVP与MVC的异同
无论MVC或是MVP模式都不可避免地存在一个弊端:
额外的代码复杂度及学习成本。这就导致了这两种开发模式也许并不是很小型应用。
但比起他们的优点,这点弊端基本可以忽略了:
(1)降低耦合度
(2)模块职责划分明显
(3)利于测试驱动开发
(4)代码复用
(5)隐藏数据
(6)代码灵活性
对于MVP与MVC这两种模式,它们之间也有很大的差异。有一些程序员选择不使用任何一种模式,有一部分原因也许就是不能区分这两种模式差异。以下是这两种模式之间最关键的差异:
MVP模式:
View不直接与Model交互,而是通过与Presenter交互来与Model间接交互
Presenter与View的交互是通过接口来进行的,更有利于添加单元测试
通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑
MVC模式:
View可以与Model直接交互
Controller是基于行为的,并且可以被多个View共享
可以负责决定显示哪个View
举个栗子(登录功能):
登录功能的M:
LoginModel
public class LoginModel {
public void login(String userName, String passWord, OnHttpResultListener onHttpResultListener){
OkHttpRequest okHttpRequest = new OkHttpRequest();
RequestBody requestBody = new FormBody.Builder()
.add("userName",userName)
.add("passWord",passWord)
.build();
okHttpRequest.postAsynHttp(requestBody,onHttpResultListener);
}
}
登录功能P:
BasePresenter
public abstract class BasePresenter <V extends BaseView>{
private LoginModel loginModel;
private V mView;
public V getView(){
return mView;
}
public void attachView(V mView){
this.mView = mView;
}
public void detachView(){
mView = null;
}
}
LoginPresenter
public class LoginPresenter extends BasePresenter<LoginView>{
private LoginModel loginModel;
public LoginPresenter() {
loginModel = new LoginModel();
}
public void login(String userName, String passWord){
loginModel.login(userName, passWord, new OnHttpResultListener() {
@Override
public void onResult(Response response) {
if (getView() != null){
getView().onResult(response);
}
}
});
}
}
登录功能的V:
BaseView
public interface BaseView {
}
LoginView
public interface LoginView extends BaseView{
void onResult(Response response);
}
登录页面:
public class LoginActivity extends AppCompatActivity implements LoginView {
public LoginPresenter loginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loginPresenter = new LoginPresenter();
loginPresenter.attachView(this);
loginPresenter.login("","");
}
@Override
public void onResult(Response response) {
}
@Override
protected void onDestroy() {
super.onDestroy();
if (loginPresenter != null){
loginPresenter.detachView();
}
}
}
学习视频: