在Android开发中,常采用 MVC(Model-View-Controller)或者MVP(Model-View-Presenter) 等框架模式。设计如图
可以看出,在 MVC 框架中,请求流程如下:
- View接受用户的请求
- View传递请求给Controller
- Controller操作Model进行数据更新
- Model通知View变化
- View根据更新的数据做出显示
而MVP框架中,请求流程如下:
- View 接受用户请求
- View 传递请求给Presenter
- Presenter做逻辑处理,修改Model
- Model 通知Presenter数据变化
- 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();
}
}
- 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进行改写
- 我们需要先对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框架中,除了将 Presenter 换成了 ViewModel 外,请求流程都和MVP类似,只是在最后一步中,由于View与ViewModel使用了双向绑定,两者的交互通过Data Binding 完成。如此使得View和控制模块的耦合更加降低,减轻了视图的压力。
还是那个栗子
我们引入Data Binding解决这个问题。
- 把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();
}
}
- 接着使用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>
- 最后在
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 思想&例子的更多相关文章
-
Android MVC MVP
从.NET的宠物商店到Android MVC MVP 1 一些闲话 记得刚进公司的时候,我们除了做常规的Training Project外,每天还要上课,接受各种技术培训和公司业务介绍.当时第一次 ...
-
MVC MVP 和 MVVM的图示
一直对于这些什么MVC MVP 和 MVVM都是云里雾里的 完全分不清楚 感觉jq上也没怎么用过,理解也很片面,画几张图也许能够大体分清他们之间的区别. 1.MVC(Model-View-Contro ...
-
android MVC &;&; MVP &;&; MVVM分析和对比
相关:http://www.cnblogs.com/wytiger/p/5305087.html 出处http://blog.csdn.net/self_study,对技术感兴趣的同鞋加群544645 ...
-
Android MVC,MVP,MVVM模式入门——重构登陆注册功能
一 MVC模式: M:model,业务逻辑 V:view,对应布局文件 C:Controllor,对应Activity 项目框架: 代码部分: layout文件(适用于MVC和MVP两个Demo): ...
-
Android MVC MVP MVVM (三)
MVVM Model-View-ViewModel的简写 在MVP基础上实现数据视图的DataBinding,数据变化,视图自动变化,反之也成立. DataBinding 启用DataBinding ...
-
Android MVC MVP MVVM (二)
MVP模型 View主要是Activity,Fragment MVP和MVC的差别 1.Model和View不再直接通信,通过中间层Presenter来实现. 2.Activity的功能被简化,不再充 ...
-
Android MVC MVP MVVM (一)
示例效果 一共三个控件,EditText,Button,TextView 成功显示账号信息,查询失败显示错误信息. <?xml version="1.0" encoding= ...
-
从.NET的宠物商店到Android MVC MVP
1 一些闲话 记得刚进公司的时候,我们除了做常规的Training Project外,每天还要上课,接受各种技术培训和公司业务介绍.当时第一次知道QA和SQA的区别.Training Project时 ...
-
Android App的设计架构:MVC,MVP,MVVM与架构经验谈
相关:http://www.cnblogs.com/wytiger/p/5996876.html 和MVC框架模式一样,Model模型处理数据代码不变在Android的App开发中,很多人经常会头疼于 ...
随机推荐
-
apk安全测试思路
一: apk安全测试 对于一款android的apk程序,主要进行的测试分两部分: 1) 接口测试 ---接口测试实际上是常见的web安全测试 2) android组件测试 --组件测试实际上是and ...
-
db2存储过程
一. 使用存储过程的好处 1. 减少客户机与服务器之间的网络使用率,以及数据库锁定保持的时间 应用程序通常在执行每个SQL语句都要跨网络两次,存储过程可以将SQL语句集中在一起, 从而使得对于每一组S ...
-
最稳定 性能最好 的 Linux 版本?
Ubuntu太他妈不稳定了,简直是一坨屎 CentOS.Ubuntu.Debian三个linux比较异同http://blog.csdn.net/educast/article/details/383 ...
- 电脑中java环境的搭建
-
全局精确流量调度新思路-HttpDNS服务详解
但凡使用域名来给用户提供服务的互联网企业,都或多或少地无法避免在有中国特色的互联网环境中遭遇到各种域名被缓存.用户跨网访问缓慢等问题.那么对于腾讯这样的域名数量在10万级别的互联网公司来讲,域名解析异 ...
-
java第十周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 1.finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中fin ...
-
浅析Java数据类型
前言: 该系列会辅以MindMap进行说明. 下面会贴两张我不同时期画的Java数据类型的思维导图,本篇主要侧重于Java的8种基本类型 MindMap-1 这张MindMap主要是根据 菜鸟教程+参 ...
-
步步为营-81-HttpModule(再谈Session)
说明:session用于记录数据信息并存放在服务器内存中,但是存在一些问题.例如当使用服务器集群是会出现session丢失等情况.虽然微软提供了一些解决方案(Session进程外存储,或者存到数据库中 ...
-
element-ui 组件源码分析整理笔记目录
element-ui button组件 radio组件源码分析整理笔记(一) element-ui switch组件源码分析整理笔记(二) element-ui inputNumber.Card .B ...
-
Swift 里字符串(十一)OC 字符串和 Swift 字符串的转换
 to OC func _bridgeToObjectiveCImpl() -> AnyObject { if _guts.isSmall { return _guts.asSmall.wit ...