MVC、MVP和MVVM都是为了解决界面呈现和逻辑代码分离而出现的开发模式。MVP和MVVM都是在MVC的基础上演化而来。
一、MVC模式
MVC是Model-View-Controller的简称。Model:模型层,负责处理数据的加载或者存储。View:视图层,负责界面数据的展示,与用户进行交互。Controller:控制器层,负责逻辑业务的处理。
MVC关系模型图
在MVC里,View是可以直接访问Model的。从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 在MVC模型里,更关注的Model的不变,而同时有多个对Model的不同显示,及View。所以,在MVC模型里,Model不依赖于View,但是View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的。
优点:
1.耦合性低
2.重用性高
3.生命周期成本低
4.部署快
5.可维护性高
6.有利软件工程化管理
缺点:
没有明确的定义
不适合大型,中等规模的应用程序
增加系统结构和实现的复杂性
视图与控制器间的过于紧密的连接
视图对模型数据的低效率访问
一般高级的界面工具或构造器不支持模式
二、MVP模式
View: 对于View层也是视图层,在View层中只负责对数据的展示,提供友好的界面与用户进行交互。在Android开发中通常将Activity或者Fragment作为View层。
Model: 对于Model层也是数据层。它区别于MVC架构中的Model,在这里不仅仅只是数据模型。在MVP架构中Model它负责对数据的存取操作,例如对数据库的读写,网络的数据的请求等。
Presenter:对于Presenter层他是连接View层与Model层的桥梁并对业务逻辑进行处理。在MVP架构中Model与View无法直接进行交互。所以在Presenter层它会从Model层获得所需要的数据,进行一些适当的处理后交由View层进行显示。这样通过Presenter将View与Model进行隔离,使得View和Model之间不存在耦合,同时也将业务逻辑从View中抽离。
MVP关系模型图
在MVP架构中将这三层分别抽象到各自的接口当中。通过接口将层次之间进行隔离,而Presenter对View和Model的相互依赖也是依赖于各自的接口。这点符合了接口隔离原则,也正是面向接口编程。在Presenter层中包含了一个View接口,并且依赖于Model接口,从而将Model层与View层联系在一起。而对于View层会持有一个Presenter成员变量并且只保留对Presenter接口的调用,具体业务逻辑全部交由Presenter接口实现类中处理。
MVC与MVP两种模式的主要区别: (最主要区别)View与Model并不直接交互,而是通过与Presenter交互来与Model间接交互。而在MVC中View可以与Model直接交互 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。而Controller是基于行为的,并且可以被多个View共享,Controller可以负责决定显示哪个View Presenter与View的交互是通过接口来进行的,更有利于添加单元测试。
优点:
1、模型与视图完全分离,我们可以修改视图而不影响模型;
2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部;
3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。
4、逻辑结构更加清晰,解决Activity代码臃肿问题
三、MVVM模式
MVVM 模式,即指 Model-View-ViewModel。它将 View 的状态和行为完全抽象化,把逻辑与界面的控制完全交给 ViewModel 处理
MVVM关系模型图
View:主要进行视图控件的一些初始设置,不应该有任何的数据逻辑操作。
Model:定义实体类,以及获取业务数据模型,比如通过数据库或者网络来操作数据等。
ViewModel:作为连接 View 与 Model 的中间桥梁,ViewModel 与 Model 直接交互,处理完业务逻辑后,通过 DataBinding 将数据变化反应到用户界面上。
优点:
低耦合度
在 MVVM 模式中,数据处理逻辑是独立于 UI 层的。ViewModel 只负责提供数据和处理数据,不会持有 View 层的引用。而 View 层只负责对数据变化的监听,不会处理任何跟数据相关的逻辑。在 View 层的 UI 发生变化时,也不需要像 MVP 模式那样,修改对应接口和方法实现,一般情况下ViewModel 不需要做太多的改动。
数据驱动
MVVM 模式的另外一个特点就是数据驱动。UI 的展现是依赖于数据的,数据的变化会自然的引发 UI 的变化,而 UI 的改变也会使数据 Model 进行对应的更新。ViewModel 只需要处理数据,而 View 层只需要监听并使用数据进行 UI 更新。
异步线程更新 Model
Model 数据可以在异步线程中发生变化,此时调用者不需要做额外的处理,数据绑定框架会将异步线程中数据的变化通知到 UI 线程中交给 View 去更新。
方便协作
View 层和逻辑层几乎没有耦合,在团队协作的过程中,可以一个人负责 UI,一个人负责数据处理。并行开发,保证开发进度。
易于单元测试
MVVM 模式比较易于进行单元测试。ViewModel 层只负责处理数据,在进行单元测试时,测试不需要构造一个 fragment/Activity/TextView 等等来进行数据层的测试。同理 View 层也一样,只需要输入指定格式的数据即可进行测试,而且两者相互独立,不会互相影响。
数据复用
ViewModel 层对数据的获取和处理逻辑,尤其是使用 Repository 模式时,获取数据的逻辑完全是可以复用的。开发者可以在不同的模块,多次方便的获取同一份来源的数据。同样的一份数据,在版本功能迭代时,逻辑层不需要改变,只需要改变 View 层即可。