MVC、MVP、MVVM详解和区别

转载请标明出处:http://blog.csdn.net/xx326664162/article/details/50478335 文章出自:薛瑄的博客

你也可以查看我的其他同类文章,也会让你有一定的收货!

1.架构设计的目的

通过设计使程序模块化,做到模块内部的高聚合和模块之间的低耦合。这样做的好处是使得程序在开发的过程中,开发人员只需要专注于一点,提高程序开发的效率,并且更容易进行后续的测试以及定位问题。但设计不能违背目的,对于不同量级的工程,具体架构的实现方式必然是不同的,切忌犯为了设计而设计,为了架构而架构的毛病。

举个简单的例子:

一个Android App如果只有3个Java文件,那只需要做点模块和层次的划分就可以,引入框架或者架构反而提高了工作量,降低了生产力;
但如果当前开发的App最终代码量在10W行以上,本地需要进行复杂操作,同时也需要考虑到与其余的Android开发者以及后台开发人员之间的同步配合,那就需要在架构上进行一些思考!

2.MVC设计架构

MVC简介

这里写图片描述

MVC全名是Model View Controller,如图,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

  • M层处理数据,业务逻辑等;
  • V层处理界面的显示结果;
  • C层起到桥梁的作用,来控制V层和M层通信以此来达到分离视图显示和业务逻辑层。

Android中的MVC

http://blog.csdn.net/feiduclear_up/article/details/46363207
http://www.cnblogs.com/liqw/p/4175325.html
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0703/1415.html

Android中界面部分也采用了当前比较流行的MVC框架,在Android中:

  • 视图层(View)
    一般采用XML文件进行界面的描述,这些XML可以理解为Android App的View。使用的时候可以非常方便的引入。同时便于后期界面的修改。逻辑中与界面对应的id不变化则代码不用修改,大大增强了代码的可维护性。显示Model层的数据结果。

  • 控制层(Controller)
    Activity处理用户交互问题,因此可以认为Activity是控制器,不要在Activity中写代码,要通过Activity交割Model业务逻辑层处理,这样做的另外一个原因是Android中的Activity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。
    Activity读取V视图层的数据(eg.读取当前EditText控件的数据),控制用户输入(eg.EditText控件数据的输入),并向Model发送数据请求(eg.发起网络请求等)。

  • 模型层(Model)
    针对业务模型,建立的数据结构相关的类,就可以理解为Android App的Model,Model是与View无关,而与业务相关的。对数据库的操作、对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的。就是应用程序中二进制的数据。

举例:

3.MVP设计架构


http://blog.csdn.net/luyi325xyz/article/details/43085409
http://blog.csdn.net/vector_yi/article/details/24719873

MVC的缺点

  • 在MVC里,View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 在MVC模型里,更关注的Model的不变,而同时有多个对Model的不同显示,及View。所以,在MVC模型里,Model不依赖于View,但是View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的。

  • 在Android开发中,Activity并不是一个标准的MVC模式中的Controller,它的首要职责是加载应用的布局和初始化用户界面,并接受并处理来自用户的操作请求,进而作出响应。随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。

MVP如何解决MVC的问题?

在MVP中:

  1. Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。其中的View是很薄的一层。
  2. Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时候可以保持Presenter的不变,即重用!
  3. 当我们将其中复杂的逻辑处理移至另外的一个类(Presneter)中时,Activity其实就是MVP模式中View,它负责UI元素的初始化,建立UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由Presenter处理).

1、方便测试:

  • 回想一下你在开发Android应用时是如何对代码逻辑进行单元测试的?是否每次都要将应用部署到Android模拟器或真机上,然后通过模拟用户操作进行测试?然而由于Android平台的特性,每次部署都耗费了大量的时间,这直接导致开发效率的降低。而在MVP模式中,处理复杂逻辑的Presenter是通过interface与View(Activity)进行交互的,这说明了什么?说明我们可以通过自定义类实现这个interface来模拟Activity的行为对Presenter进行单元测试,省去了大量的部署及测试的时间。

  • 我们还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试 —— 而不需要使用自动化的测试工具。

  • 我们甚至可以在Model和View都没有完成时候,就可以通过编写Mock Object(即实现了Model和View的接口,但没有具体的内容的)来测试Presenter的逻辑。

2、如果View很简单:

  • 有人提出了Presenter First的设计模式,就是根据User Story来首先设计和开发Presenter。在这个过程中,能够把信息显示清楚就可以了。在后面,根据需要再随便更改View,而对Presenter没有任何的影响了。

3、如果UI比较复杂,而且相关的显示逻辑还跟Model有关系,就可以在View和Presenter之间放置一个Adapter。

  • 由这个 Adapter来访问Model和View,避免两者之间的关联。
  • 而同时,因为Adapter实现了View的接口,从而可以保证与Presenter之间接口的不变。

这样就可以保证View和Presenter之间接口的简洁,又不失去UI的灵活性。

在MVP模式里,View只应该有简单的Set/Get的方法,用户输入和设置界面显示的内容,除此就不应该有更多的内容,绝不容许直接访问Model —— 这就是与MVC很大的不同之处。

MVP简介

MVP是一种使用广泛的基础架构模式,使用基于事件驱动的应用框架。MVP从更早的MVC框架演变过来的一种框架,与MVC有一定的相似性。
这里写图片描述

具体到Android App中,一般可以将App根据程序的结构进行纵向划分,根据MVP可以将App分别为模型层(M),UI层(V)和逻辑层(P)。

UI层一般包括Activity,Fragment,Adapter等直接和UI相关的类,UI层的Activity在启动之后实例化相应的Presenter,App的控制权后移,由UI转移到Presenter,两者之间的通信通过BroadCast、Handler或者接口完成,只传递事件和结果。

举例: UI层通知逻辑层(Presenter)用户点击了一个Button,逻辑层(Presenter)自己决定应该用什么行为进行响应,该找哪个模型(Model)去做这件事,最后逻辑层(Presenter)将完成的结果更新到UI层。

MVP框架由3部分组成:View负责显示,Presenter负责逻辑处理,Model提供数据。在MVP模式里通常包含3个要素(加上View interface是4个):

  • View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity)

  • Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合)

  • Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。

  • View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试。这是非必需的

MVC和MVP的区别

http://cdn0.jianshu.io/p/eb295904d9f8

MVP模式:

  • View不直接与Model交互,而是通过与Presenter交互来与Model间接交互,所有的交互都发生在Presenter内部
  • Presenter与View的交互是通过接口来进行的,更有利于添加单元测试
  • 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑

MVC模式:

  • View可以与Model直接交互,View会从直接Model中读取数据而不是通过 Controller
  • Controller是基于行为的,并且可以被多个View共享
  • 可以负责决定显示哪个View

MVP的优点

1、模型与视图完全分离,我们可以修改视图而不影响模型;

2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部;

3、我们可以将一个Presenter用于多个视图(将视图A改变为视图B),而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁;

4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。

MVP的变种:Passive View

http://www.cnblogs.com/artech/archive/2010/03/25/1696205.html

MVP的变种有很多,其中使用最广泛的是Passive View模式,即被动视图。
在这种模式下,整个框架内部模块之间的逻辑操作均由Presenter控制,View仅仅是整个操作的汇报者和结果接收者

  • View和Model之间不能直接交互,View通过Presenter与Model打交道。Presenter接受View的UI请求,完成简单的UI处理逻辑,并调用Model进行业务处理,并调用View将相应的结果反映出来。View直接依赖Presenter,
  • 但是Presenter间接依赖View,它直接依赖的是View实现的接口。
    这里写图片描述

Passive View模式的基本特征总结

Passive View,顾名思义,View是被动的。那么主动是谁呢?答案是Presenter。对于Presenter的主动性,我个人是这么理解的:

  • Presenter是整个MVP体系的控制中心,而不是单纯的处理View请求的人;
  • View仅仅是用户交互请求的汇报者,对于响应用户交互相关的逻辑和流程,View不参与决策,真正的决策者是Presenter;
  • View向Presenter发送用户交互请求应该采用这样的口吻:“我现在将用户交互请求发送给你,你看着办,需要我的时候我会协助你”,不应该是这样:“我现在处理用户交互请求了,我知道该怎么办,但是我需要你的支持,因为实现业务逻辑的Model只信任你”;
  • 对于绑定到View上的数据,不应该是View从Presenter上“拉”回来的,应该是Presenter主动“推”给View的;
  • View尽可能不维护数据状态,因为其本身仅仅实现单纯的、独立的UI操作; Presenter才是整个体系的协调者,它根据处理用于交互的逻辑给View和Model安排工作。

MVP架构存在的问题与解决办法

  • 加入模板方法(Template Method)

转移逻辑操作之后可能部分较为复杂的Activity内代码量还是不少,于是需要在分层的基础上再加入模板方法(Template Method)。

具体做法是在Activity内部分层。其中最顶层为BaseActivity,不做具体显示,而是提供一些基础样式,Dialog,ActionBar在内的内容,展现给用户的Activity继承BaseActivity,重写BaseActivity预留的方法。如有必要再进行二次继承,App中Activity之间的继承次数最多不超过3次。

  • Model内部分层

模型层(Model)中的整体代码量是最大的,一般由大量的Package组成,针对这部分需要做的就是在程序设计的过程中,做好模块的划分,进行接口隔离,在内部进行分层。

  • 强化Presenter

强化Presenter的作用,将所有逻辑操作都放在Presenter内也容易造成Presenter内的代码量过大,那该怎么办呢?
解决方法:

  • 在UI层和Presenter之间设置中介者Mediator,将例如数据校验、组装在内的轻量级逻辑操作放在Mediator中;
  • 在Presenter和Model之间使用代理Proxy;

通过上述两者分担一部分Presenter的逻辑操作,但整体框架的控制权还是在Presenter手中。Mediator和Proxy不是必须的,只在Presenter负担过大时才建议使用。

这里写图片描述

4、MVVM设计架构

http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html
http://www.jianshu.com/p/4e3220a580f6
示例:http://www.oschina.net/p/mvvm-

最近一段时间MVP模式已经成为Android应用开发UI层架构设计的主流趋势。类似TED MOSBY,nucleus和mortar之类的框架都引入了Presenters来帮助我们搭建简洁的app架构。它们也(在不同的程度上)帮助我们处理Android平台上臭名昭著的设备旋转和状态持久化等问题。MVP模式也有助于隔离样板代码,虽然这并不是MVP模式的设计初衷。

在Google I/O 2015上,伴随着Android M预览版发布的Data Binding兼容函数库改变了这一切。

MVVM简介

这里写图片描述

基本上与 MVP 模式完全一致,MVVM其中的VM是ViewModel的缩写,ViewModel可以理解成是View的数据模型和Presenter的合体,ViewModel和View之间的交互通过Data Binding完成,而Data Binding可以实现双向的交互,View的变动,自动反映在 ViewModel。这就使得视图和控制层之间的耦合程度进一步降低,关注点分离更为彻底,同时减轻了Activity的压力。

AngularEmber 都采用这种模式。

刚开始理解这些概念的时候认为这几种模式虽然都是要将view和model解耦,但是非此即彼,没有关系,一个应用只会用一种模式。后来慢慢发现世界绝对不是只有黑白两面,中间最大的一块其实是灰色地带,同样,这几种模式的边界并非那么明显,可能你在自己的应用中都会用到。实际上也根本没必要去纠结自己到底用的是MVC、MVP还是MVVP,不管黑猫白猫,捉住老鼠就是好猫。

5、总结

MVC->MVP->MVVM演进过程

MVC -> MVP -> MVVM 这几个软件设计模式是一步步演化发展的,MVP 隔离了MVC中的 M 与 V 的直接联系后,靠 Presenter 来中转,所以使用 MVP 时 P 是直接调用 View 的接口来实现对视图的操作的,这个 View 接口的东西一般来说是 showData、showLoading等等。M 与 V已经隔离了,方便测试了,但代码还不够优雅简洁,所以 MVVM 就弥补了这些缺陷。MVVM 是从 MVP 的进一步发展与规范,在 MVVM 中就出现的 Data Binding 这个概念,意思就是 View 接口的 showData 这些实现方法可以不写了,通过 Binding 来实现。

如果把这三者放在一起比较,先说一下三者的共同点,也就是Model和View:

  • Model:数据对象,同时,提供本应用外部对应用程序数据的操作的接口,也可能在数据变化时发出变更通知。Model不依赖于View的实现,只要外部程序调用Model的接口就能够实现对数据的增删改查。

  • View:UI层,提供对最终用户的交互操作功能,包括UI展现代码及一些相关的界面逻辑代码。

三者的差异在于如何粘合View和Model,实现用户的交互操作以及变更通知

  • Controller
    Controller接收View的操作事件,根据事件不同,或者调用Model的接口进行数据操作,或者进行View的跳转,从而也意味着一个Controller可以对应多个View。Controller对View的实现不太关心,只会被动地接收,Model的数据变更不通过Controller直接通知View,通常View采用观察者模式监听Model的变化。

  • Presenter
    Presenter与Controller一样,接收View的命令,对Model进行操作;与Controller不同的是Presenter会反作用于View,Model的变更通知首先被Presenter获得,然后Presenter再去更新View。一个Presenter只对应于一个View。根据Presenter和View对逻辑代码分担的程度不同,这种模式又有两种情况:Passive View和Supervisor Controller。

  • ViewModel
    注意这里的“Model”指的是View的Model,跟MVVM中的一个Model不是一回事。所谓View的Model就是包含View的一些数据属性和操作的这么一个东东,这种模式的关键技术就是数据绑定(data binding),View的变化会直接影响ViewModel,ViewModel的变化或者内容也会直接体现在View上。这种模式实际上是框架替应用开发者做了一些工作,开发者只需要较少的代码就能实现比较复杂的交互。

先实现,再重构吧。直接考虑代码不臃肿得话,不知道什么时候才能写好了

先实现,再重构吧。直接考虑代码不臃肿得话,不知道什么时候才能写好了

先实现,再重构吧。直接考虑代码不臃肿得话,不知道什么时候才能写好了

(重要的事情说三遍)

参考:http://m.itgoodboy.com/ruanjian/8577.html
http://www.tianmaying.com/tutorial/AndroidMVC
http://blog.csdn.net/napolunyishi/article/details/22722345

关注我的公众号,轻松了解和学习更多技术
这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛瑄

文章不错,请博主吃包辣条

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值