在Android开发中,常采用 MVC(Model-View-Controller)或者MVP(Model-View-Presenter) 等框架模式。设计如图

 
mvc mvp

可以看出,在 MVC 框架中,请求流程如下:

  1. View接受用户的请求
  2. View传递请求给Controller
  3. Controller操作Model进行数据更新
  4. Model通知View变化
  5. View根据更新的数据做出显示

而MVP框架中,请求流程如下:

  1. View 接受用户请求
  2. View 传递请求给Presenter
  3. Presenter做逻辑处理,修改Model
  4. Model 通知Presenter数据变化
  5. Presenter 更新View

相比于MVC,MVP则使用Presenter解除了View与Model的耦合,Presenter将Model的变化返回给View。

举个栗子

小明需要开发一个功能,当点击“find student id”按钮时,可以查询到他自己的学号。

 
栗子

对于MVC 实现,应该是这样的:

1.先实现一个 model,需要有通知View更新的能力,当model加载成功,如从db、获取后,需要告知View:

public class StudentModel {

    String mId;
WelcomeActivity mActivity; public StudentModel (WelcomeActivity activity) {
this.mActivity = activity;
}
public void loadModel (){
//search from db or intent
mId = "1201030018";
mActivity.updateUI(this);
} }

2.Controller : 我们为了更好的理解MVC,将Activity进行了拆解。提取了一个简单的Controller

public class WelcomeController {

    WelcomeActivity mActivity;
StudentModel mStudent; WelcomeController (WelcomeActivity activity) {
this.mActivity = activity;
} public void loadData (){
mStudent = new StudentModel(mActivity);
mStudent.loadModel();
}
}
  1. View : View需要发出点击事件,并且传递给Controller,同时需要根据Model更新UI:
public class WelcomeActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
//省略
final WelcomeController controller = new WelcomeController(this);
mFindBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
controller.loadData();
}
});
} public void updateUI (StudentModel model) {
mID.setText(model.mId);
}
}

调用链是:

View:OnClick ->

Controller:loadData->

Model:loadModel->

View:updateUI

这里为了更明显的表明意图,将Activity单纯的看做一个View。

MVP 改写

同样的例子,我们使用MVP进行改写

  1. 我们需要先对Model进行封装,当loadModel后,不直接通知View更新,而是通知监听方(Presenter):
public class StudentModel {
String mId;
OnGetListener mListener; public StudentModel (OnGetListener listener) {
this.mListener = listener;
}
public void loadModel (){
//search from db or intent
mId = "1201030018";
if (mListener != null) {
mListener.onSuccess(this);
}
}
interface OnGetListener {
void onSuccess (StudentModel student);
}
}

2.再定义Presenter ,接收到来自View的操作命令后,进行逻辑处理,处理Model,修改完成后 通知View进行修改。

public class WelcomePresenter {

    WelcomeActivity mActivity;
StudentModel mStudent; WelcomePresenter (WelcomeActivity activity) {
this.mActivity = activity;
} public void loadData (){
mStudent = new StudentModel(new StudentModel.OnGetListener() {
@Override
public void onSuccess(StudentModel student) {
mActivity.updateUI(student);
}
});
}
}

3.对于View,操作方式只是修改了持有的对象 WelcomeController->WelcomePresenter,其他保持不变。

这时调用流程变成了:

View:OnClick ->

Presenter:loadData->

Model:loadModel->

Presenter:onSuccess>

View:updateUI

我们将View的数据更新 从Model->View,转变成了Presenter->View,解除了View和Model的耦合。

mvvm

早些年微软WPF提出的数据绑定系统与Presentation Model相结合的做法,能使开发人员将View和逻辑分离,称之Model-View-ViewModel(MVVM)。

在Android 借助Google提出的 DataBinding 框架完成 双向绑定操作。

DataBinding用法可以参考: https://developer.android.com/topic/libraries/data-binding/index.html

调用链路如下:

 
MVVM

可以看到,在MVVM框架中,除了将 Presenter 换成了 ViewModel 外,请求流程都和MVP类似,只是在最后一步中,由于View与ViewModel使用了双向绑定,两者的交互通过Data Binding 完成。如此使得View和控制模块的耦合更加降低,减轻了视图的压力。

还是那个栗子

我们引入Data Binding解决这个问题。

  1. 把Controller\Presenter扔掉,先写一个ViewModel

    这个VM的概念是一个和视图相关的模型,因此可以和DAO相关的模型不一样,因为我们只需要展示student id的数据以及click事件,以及loadData行为,用来从Model中获取数据,于是我们实现了一个VM :

这里我们需要遵循Data Binding的语法,如继承自BaseObservable,数据更新后调用notifyChange方法等。

public class StudentViewModel extends BaseObservable{

    String studentID;
View.OnClickListener btnListener;
//省略get set public StudentViewModel() {
btnListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
loadData();
}
};
} public void loadData() {
StudentModel model = new StudentModel(new StudentModel.OnGetListener() {
@Override
public void onSuccess(StudentModel student) {
setStudentID(student.mId);
}
});
model.loadModel();
}
}
  1. 接着使用databinding语法 对 xml 进行数据绑定,我们将 Click事件、输出结果都绑定到VM上。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable name="userVM" type="com.moon.coderread.StudentViewModel"/>
</data>
<LinearLayout
//省略
<TextView
android:id="@+id/id"
android:layout_width="match_parent"
android:layout_height="20dp"
android:text="@{userVM.studentID}"/>
<Button
android:id="@+id/findBtn"
android:onClick="@{userVM.btnListener}"
android:text="find Student ID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
  1. 最后在View(Activity)中引入VM :
public class WelcomeActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) { ActivityWelcomeBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_welcome); final StudentViewModel studentViewModel = new StudentViewModel();
binding.setUserVM(studentViewModel);
} }

这样就完成了最基本的MVVM 栗子。

现在我们的Activity看起来很清爽,不用再处理Click事件、以及updateUI了。

总结

各种MV+X模式的发展,实质上就是将Model与View之间以一种低耦合、低成本的方式进行控制。从Presenter到ViewModel的转变,借助了Data Binding的方式实现了双向的数据绑定,减少了视图模块和控制模块的耦合。随着Google Data Binding技术的不断更新完善,相信MVVM模式将在Android平台下应用得更加广泛。

栗子仅仅是

上面仅仅是以最简单的方式来描述了一下 MV+X模式的实现流程,在实践项目里场景会复杂数倍。

作者:andChen
链接:https://www.jianshu.com/p/9df92995ee26
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

[转载]Android MVC,MVP和MVVM 思想&例子的更多相关文章

  1. Android MVC MVP

    从.NET的宠物商店到Android MVC MVP   1 一些闲话 记得刚进公司的时候,我们除了做常规的Training Project外,每天还要上课,接受各种技术培训和公司业务介绍.当时第一次 ...

  2. MVC MVP 和 MVVM的图示

    一直对于这些什么MVC MVP 和 MVVM都是云里雾里的 完全分不清楚 感觉jq上也没怎么用过,理解也很片面,画几张图也许能够大体分清他们之间的区别. 1.MVC(Model-View-Contro ...

  3. android MVC && MVP && MVVM分析和对比

    相关:http://www.cnblogs.com/wytiger/p/5305087.html 出处http://blog.csdn.net/self_study,对技术感兴趣的同鞋加群544645 ...

  4. Android MVC,MVP,MVVM模式入门——重构登陆注册功能

    一  MVC模式: M:model,业务逻辑 V:view,对应布局文件 C:Controllor,对应Activity 项目框架: 代码部分: layout文件(适用于MVC和MVP两个Demo): ...

  5. Android MVC MVP MVVM (三)

    MVVM Model-View-ViewModel的简写 在MVP基础上实现数据视图的DataBinding,数据变化,视图自动变化,反之也成立. DataBinding 启用DataBinding ...

  6. Android MVC MVP MVVM (二)

    MVP模型 View主要是Activity,Fragment MVP和MVC的差别 1.Model和View不再直接通信,通过中间层Presenter来实现. 2.Activity的功能被简化,不再充 ...

  7. Android MVC MVP MVVM (一)

    示例效果 一共三个控件,EditText,Button,TextView 成功显示账号信息,查询失败显示错误信息. <?xml version="1.0" encoding= ...

  8. 从.NET的宠物商店到Android MVC MVP

    1 一些闲话 记得刚进公司的时候,我们除了做常规的Training Project外,每天还要上课,接受各种技术培训和公司业务介绍.当时第一次知道QA和SQA的区别.Training Project时 ...

  9. Android App的设计架构:MVC,MVP,MVVM与架构经验谈

    相关:http://www.cnblogs.com/wytiger/p/5996876.html 和MVC框架模式一样,Model模型处理数据代码不变在Android的App开发中,很多人经常会头疼于 ...

随机推荐

  1. 【uva 1612】Guess(算法效率,2种想法)

    题意:已知 N 位选手的3题的预期得分,得分要不全拿,要不为0.且知道最后的实际名次,而且得分相同的选手,ID小的排在前面.问这样的名次可能吗.若可能,输出最后一名的最高可能得分.(N≤16384) ...

  2. Bubble Cup 13 - Finals [Online Mirror, unrated, Div. 1] K. Lonely Numbers (数学)

    题意:定义两个数\(a,b\)是朋友,如果:\(gcd(a,b)\),\(\frac{a}{gcd(a,b)}\),\(\frac{b}{gcd(a,b)}\)能构成三角形,现在给你一个正整数\(n\ ...

  3. WSL2 VS Code远程开发.Net Core

    修改 我们打开一个页面,随便修改一下,保存,结果会出现错误:Unable to write file (NoPermissions (FileSystemError): Error: EACCES: ...

  4. Spring Cloud实战 | 第十一篇:Spring Cloud Gateway 网关实现对RESTful接口权限控制和按钮权限控制

    一. 前言 hi,大家好,这应该是农历年前的关于开源项目 的最后一篇文章了. 有来商城 是基于 Spring Cloud OAuth2 + Spring Cloud Gateway + JWT实现的统 ...

  5. Kubernets二进制安装(9)之部署主控节点控制器controller-manager

    kube-controller-manager运行控制器,它们是处理集群中常规任务的后台线程 Controller Manager就是集群内部的管理控制中心,由负责不同资源的多个Controller构 ...

  6. Python & file operation mode

    Python & file operation mode create/read/write/append mode https://docs.python.org/3/library/fun ...

  7. js form.onformData事件

    在表单提交前修改数据,此事件在submit之后 f1.addEventListener("formdata", (e) => { e.formData.append(&quo ...

  8. c++ x86_x64挂钩函数 传递寄存器表

    https://github.com/januwA/GameCheat #include "pch.h" #include <iostream> #include &l ...

  9. USDN稳定币应用区块链旅游业

    比特币是区块链1.0时代的标志性产品,稳定币则是区块链2.0时代的标志性产品.在稳定币鼻祖USDT爆出"超发"新闻后曾引发市场的动荡,之后新兴稳定币如春笋般涌现.据不完全同济,目前 ...

  10. SPC算力空投来袭!对话NGK!华盛顿金融特别报道

    近日华盛顿金融时报联合波士顿商业报等多家知名金融媒体专访了NGK. NGK代表马特彼得森就表示NGK在新的一年里将会继续以生态建设者为中心,以打造高倍币孵化器为目标,不断推进NGK项目的落地,踏踏实实 ...