前言
在前端技术的快速发展过程中,MVC(模型-视图-控制器)、MVP(模型-视图-表示器)和MVVM(模型-视图-视图模型)也得到了很多使用。然而,这三种框架模式非常相似,不易分清,易于混淆。本文重在讲述它们的概念和应用场景及它们之间的细微差别,使我们更好的理解和使用这三种框架模式。
1.MVC
MVC全名是Model View Controller,是模型(Model)-视图(View)-控制器(Controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。它强制将业务数据(Model)与用户界面(View)隔离,使用控制器(Controller)来管理逻辑和用户输入。其模式图为:
MVC框架模式其三个部分的含义为:
- Model:负责在数据库中存取数据,是应用程序中用于处理应用程序数据逻辑的部分。Model不涉及用户界面,也不涉及表示层,而是负责提供应用程序需要的特殊格式的数据。
- View:描绘的是Model的当前状态,用来显示数据,是应用程序中处理数据显示的部分。View是Model的可视化表示,表示当前状态的筛选视图。用户可以与View交互,包括读取和编辑Model,而更新Model的工作实际由Controller完成。
- Controller:通常控制器负责从View读取数据,控制用户输入,并向Model发送数据,是应用程序中处理用户交互的部分。Controller是Model和View之间的中介,当用户操作View时,它通常负责更新Model。
MVC的优势
- 整体维护更容易。数据中心是否改变,什么时候需要更新应用程序这点很清楚。
- 解耦Model和View,意味着它能够更直接地编写业务逻辑的单元测试。
- 在整个程序应用中,减少了底层Model和Controller代码的重复,更加高效,易于维护。
- 由于表示和逻辑的分离,更加易于分工协作,可以让负责核心逻辑的开发人员和负责用户界面的开发人员同时工作。
2.MVP
MVP(模型-视图-表示器)是MVC框架模式的一种衍生模式,专注于改进表示逻辑。MVP的全称为Model-View-Presenter,Model提供数据,View负责显示,Presenter负责逻辑的处理。在MVP中,当Model变化时,监控Model和更新View,Presenter将Model有效地绑定至View。其模式图为:
MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。
在MVP里,Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。而且,Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时候可以保持Presenter的不变,即重用!
MVP最常用于企业级应用中,因为这类项目需要尽可能多地重用表示逻辑。具有非常复杂的View和大量用户交互的应用程序可能发现MVC并不能完全符合要求,因为这需要更多的控制器。在MVP中,这些复杂的逻辑可言封装在一个表示器中,可以极大的简化维护工作。
MVP的优势:
- 模型与视图完全分离,我们可以修改视图而不影响模型。
- 可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部。
- 我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
- 如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。
3.MVVM
MVVM(模型-视图-视图模型)是一种基于MVC和MVP的架构模式,它试图更清晰地将用户界面开发从应用程序的业务逻辑与行为中分离。MVVM的全称为Model-View-ViewModel,其中可以将ViewModel看成一个专门的Controller,充当数据转换器,它将Model信息转变成View信息,还将命令从View传递到Model。为此,很多这种模式的实现都要利用声明式数据绑定来实现将View工作从其他层分离。其模式图为:
View与ViewModel:View与ViewModel之间经过数据绑定和事件进行通信,ViewModel不只暴露Model属性,还会访问其他方法和验证类的特性。View处理自己的用户界面事件,必要时将它们映射到ViewModel。Model和ViewModel上的属性通过双向数据绑定进行同步和更新。数据触发器也可以使我们进一步地对Model属性的状态变化做出反应。
ViewModel与Model:ViewModel似乎完全负责MVVM中的Model,ViewModel可以为了数据绑定而暴露Model或Model属性,也可以包含接口,用于获取和操作在View中暴露的属性。
MVVM优势:
- 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
- MVVM使View抽象化,让很多view重用这段视图逻辑,减少代码背后所需的业务逻辑。
- 独立开发,使得UI和为UI提供驱动的行为模块的并行开发变得更容易。
- ViewModel在单元测试中的使用比在事件驱动代码中的使用更加容易。
- 不需要考虑UI自动化和交互就可以测试ViewModel。
缺点:
- MVVM不适合简单UI项目。
- 数据绑定是声明式的,虽然使用方便,但比命令式代码更难调试,在命令式代码中,我们打断点就好了。
- 大型应用程序中的数据绑定将会产生大量的标记。
- 在较大型应用程序中,预先设计大量的ViewModel可能更加困难。
总结
MVP和MVVM都是MVC衍生出来的,它们之间的不同在于每一层对其他层的依赖,以及它们是如何紧密相互绑定的。
- 在MVC中,View了解Controller,Controller了解Model,View也可以直接访问Model。由于View直接访问Model,缺少一定的控制,可能会带来安全性和性能成本,这由程序的复杂性决定。MVVM试图解决这方面的问题。
- 在MVP中,Controller被Presenter所替代。Presenter位于View和Model之间,监听二者事件,协调它们之间的行动。与MVVM不同,MVP没有将View绑定至ViewModel的机制,这就需要依赖每个View来实现用于让Presenter与View进行交互的接口。
- 在MVVM中,Model可以特定于View,可以包含状态和逻辑信息,无需向View暴露整个Model。与MVP中的Presenter不同,引用View时不需要ViewModel。View可以绑定到ViewModel上的属性,而属性将Model包含的数据提供给View展示。View的抽象减少了背后所需的代码逻辑。然而,View与ViewModel之间需要进行解释,会有性能消耗。
MVC、MVP、MVVM这三种框架模式在不同的业务上有不同的适用性,只要能满足业务需要就行。