在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. Centos 7 安装nginx指定版本

    官方版本列表:http://nginx.org/download/ 1.安装 wget http://nginx.org/download/nginx-1.10.3.tar.gz tar -zxvf ...

  2. UML类图设计神器 AmaterasUML 的配置及使用

    最近写论文需要用到UML类图,但是自己画又太复杂,干脆找了个插件,是Eclipse的,也有IDEA的,在这里我简单说下Eclipse的插件AmaterasUML 的配置与使用吧. 点击这里下载Amat ...

  3. C++ Primer笔记

    C++ Primer笔记 ch2 变量和基本类型 声明 extern int i; extern int i = 3.14;//定义 左值引用(绑定零一变量初始值,别名) 不能定义引用的引用:引用必须 ...

  4. React components render order All In One

    React components render order All In One components render order / components lifecycle DOM tree ren ...

  5. git config [section] solutions

    git config [section] solutions fix git [section] warnings global config $ vim ~/.gitconfig [user] em ...

  6. Node.js & process.env & OS Platform checker

    Node.js & process.env & OS Platform checker Window 10 Windows 7 ia32 CentOS $ node # process ...

  7. Flutter 使用p5

    p5 工作示例 install dependencies: p5: ^0.0.5 main.dart import 'package:flutter/material.dart'; import &q ...

  8. HANNAH WHITE:不拖延的人生是什么样子的?

    不拖延的人生,究竟是什么样子呢?近日,星盟投资总经理HANNAH在一档人物采访栏目中表示,不拖延的人生,真的是太爽了! HANNAH在栏目中讲了一个曾经公司同事的故事.她说,那位同事总是喜欢拖延.每次 ...

  9. 算法型稳定币USDN有什么魔力引发市场热潮?

    最近比特币重新突破了8万大关,区块链行业又再次火爆起来,吸引了圈内圈外人的火热讨论,而这其中市场投资者讨论最频繁的就要属算法型稳定币USDN了. USDN是基于NGK.IO区块链中的稳定币, 1枚US ...

  10. NGK公链DeFi发力,Baccarat项目引爆流动性挖矿热潮

    DeFi市值屡创新高,在这条康庄大道上,人们摩拳擦掌,就像90年代美国西部淘金热一般.DeFi带来的流动性挖矿构成了今年加密货币一道靓丽的风景线,而人们手握的不再是当年的锄头铲子,而是一串代码. 随着 ...