经过代码对比,详细讲解MVC,MVP,MVVM之间应该如何选择,以及对Android单元测试的探索。本文的侧重点在于如何选择,并无对每种架构模式概念展开详解(网络上这方面的文章有不少,你们能够自行搜索)。java
展现任务详情的功能,详情View层的经过xml来写的,请求数据相关的代码会在Model层提供接口,而后经过Activity对View和Model层进行链接。android
M:
public interface TaskModel {
void loadTask(String taskId, OnTaskListener listener);
}
V:
taskdetail.xml:界面布局文件,采用XML进行描述,属于V层的一部分。
C & V:
TaskDetailActivity:C层和V层
public class TaskDetailActivity {
private void initView() {
taskModel.loadTask(taskId, new OnTaskListener() {
public void onSuccess(Task task) {
//V层代码,可是目前耦合到了C层
detailTitle.setText(task.getTitle);
}
});
}
}复制代码
展现任务详情的功能,详情View层的经过xml和Activity来完成,请求数据相关的代码会在Model层提供接口,而后经过Presenter对View和Model层进行链接。编程
M:
public interface TaskModel {
void loadTask(String taskId, OnTaskListener listener);
}
V:
taskdetail.xml:界面布局文件,采用XML进行描述,属于V层的一部分。
public class TaskDetailActivity implements TaskDetailView {
public void showTask(Task task) {
detailTitle.setText(task.getTitle);
}
}
P:
public class TaskDetailPresenter implements Presenter {
public void getTask() {
taskModel.loadTask(taskId, new OnTaskListener() {
public void onSuccess(Task task) {
//经过接口回调到V层更新UI
taskDetailView.showTask(task);
}
});
}
}复制代码
展现任务详情的功能,详情View层的经过xml和Activity来完成,请求数据相关的代码会在Model层提供接口,而后经过ViewModel对View和Model层进行链接。网络
M:
public interface TaskModel ... void loadTask(String taskId, OnTaskListener listener);
V:
taskdetail.xml:界面布局文件,采用XML进行描述,绑定规则在xml中进行定义。
TaskDetailActivity:Activity主要是初始化和补充的功能。
VM:
TaskDetailViewModel {
public void getTask() {
taskModel.loadTask(taskId, new OnTaskListener() {
public void onSuccess(Task task) {
//经过绑定技术更新UI,作到数据独立于UI
taskDeatailViewBinding.setTask(task);
}
});
}
}复制代码
经过以上对比,选择了MVP+DataBinding,此架构模式基于MVP,并使用DataBinding库来显示数据并绑定View。它并不遵循严格的MVVM或MVP模式,由于它同时使用了ViewModel和Presenter。架构
这是我上篇文章咱们为何要使用DataBinding,里面经过代码的对比,总结说明为何要使用DataBinding的技术,有兴趣的同窗能够阅读一下,在这里我把文章里的一小段总结贴出来:mvc
DataBinding为数据驱动:数据变化后自动更新UI;事件处理:直接找到目标实例处理用户操做的事件。这样咱们就不须要和UI或者控件打交道,只须要在java代码中处理业务逻辑就行了,很是清晰,其他的统一交给binding库去完成。下降了代码耦合度,使得数据独立于UI,对之后程序的变化和维护都有积极的影响。框架
展现任务详情的功能,数据和事件绑定与基础MVP代码的对比。mvvm
//普通MVP 任务详情代码示例:
public void onCreateView(...) {
detailTitle = (TextView) root.findViewById(R.id.task_detail_title);
detailComplete = (CheckBox) root.findViewById(R.id.task_detail_complete);
detailComplete.setOnCheckedChangeListener(
(cb, isChecked) -> presenter.completeChanged(task, isChecked)
);
}
@Override
public void showDescription(String title) {
detailTitle.setText(title);
}
//xml文件省略...
//MVP+DataBinding 任务详情代码示例:
@Override
public void showTask(Task task) {
viewDataBinding.setTask(task);
}
//能够经过布局文件直接绑定到数据模型的属性(xml文件)
<TextView
android:id="@+id/task_detail_title"
android:text="@{task.title}" />
//事件绑定一样能够直接在布局文件中实现(xml文件)
<CheckBox
android:id="@+id/task_detail_complete"
android:checked="@{task.completed}"
android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />复制代码
不须要Android环境,所以使用Junit测试便可 ide
使用Google建议的Espresso进行UI的测试(须要依赖Android环境)布局
就目前实践过程当中,会发现须要为测试写一些额外的方法,不是太舒服。而且写两层测试,工做量变大。还有覆盖率以及维护的问题,一直在探索最佳实践,会在之后的文章里面和你们分享。
本片文章来自于本身的编程实战,写的很差的地方请你们帮忙指正,但愿能帮助你们选到合适本身的架构模式。谢谢阅读。