架构选型之MVC、MVP、MVVM

文章是转的,网上看过的唯二的我读过关于“MVC、MVP、MVVM”最精准到位的文章。两篇文章最出彩的地方是从UI到数据流向,详细且细致的揭示了三者的区别。

MVC、MVP、MVVM的区别和联系<span class=”hint–top hint–error hint–medium hint–rounded hint–bounce” aria-label=”链接找不到了#

“>[1]

在开始正式讲解之前,先举一个例子,如图1所示。这是一个很简单的计数器,单击“减”按钮,数字就会减 1;单击“加”按钮,数字就会加 1。

简单的计数器
图1:MV 系列框架例子

接下来需要知道的是,在 MV 系列框架中,M 和 V 指 Model 层和 View 层,但是其功能会因为框架的不同而变化:

  • Model 层很好理解,就是存储数据;
  • View 层则是展示数据,读者能看见这个例子,完全就是因为存在 View 层。

虽然在不同的框架中, View 层和 Model 层的内容可能会有所差别,但是其基础功能不变,变的只是数据的传输方式。

下面就从这个例子开始了解 MV 系列框架的概念。

1. MVC 框架#

MVC 框架是 MVC、MVP、MVVM 这3个框架中历史最悠久的。20 世纪 70 年代,施乐公司发明了 Smalltalk 语言,用来编写图形界面的应用程序,脱离了 DOS 系统,让系统可视化,不用一直看着黑白的界面。

在 Smalltalk 发展到 80 版本的时候,MVC 框架被一位工程师提出来,MVC 框架的出现在很大程度上降低了应用程序的管理难度,之后被广泛应用于构架桌面和服务器应用程序。MVC 框架如图2所示(实线表示调用,虚线表示通知)。

MVC框架图
图2:MVC 框架图

Controller 是 MVC 中的 C,指控制层,在 Controller 层会接收用户所有的操作,并根据写好的代码进行相应的操作——触发 Model 层,或者触发 View 层,抑或是两者都触发。

需要注意:Controller 层触发 View 层时,并不会更新 View 层中的数据,View 层中的数据是通过监听 Model 层数据变化而自动更新的,与 Controller 层无关。

MVC 框架流程如图3所示:

MVC框架流程图
图3:MVC 框架流程图

从图3中可以看出,MVC 框架主要有两个缺点:

  • MVC 框架的大部分逻辑都集中在 Controller 层,代码量也都集中在 Controller 层,这带给 Controller 层很大的压力,而已经有独立处理事件能力的 View 层却没有用到。
  • 还有一个问题,就是 Controller 层和 View 层之间是一一对应的,断绝了 View 层复用的可能,因而产生了很多冗余代码。

为了解决以上问题,MVP 框架被提出来。

2. MVP 框架#

首先需要知道,MVP 不是指 Most Valuable Player,而是指 Model-View-Presenter。

MVP 框架比 MVC 框架大概晚出现 20 年,1990 年,MVP 由 IBM 的子公司 Taligent 公司提出,它最开始好像是一个用于 C++ CommonPoint 的框架,这种说法正确与否这里不做考证,先来看一下 MVP 框架图(图4)。

MVP框架图
图4:MVP框架图

在 MVC 框架中,View 层可以通过访问 Model 层来更新,但在 MVP 框架中,View 层不能再直接访问 Model 层,必须通过 Presenter 层提供的接口,然后 Presenter 层再去访问 Model 层。

这看起来有点多此一举,但用处着实不小,主要有两点:

  • 首先是因为 Model 层和 View 层都必须通过 Presenter 层来传递信息,所以完全分离了 View 层和 Model 层,也就是说,View 层与 Model 层一点关系也没有,双方是不知道彼此存在的,在它们眼里,只有 Presenter 层。
  • 其次,因为 View 层与 Model 层没有关系,所以 View 层可以抽离出来做成组件,在复用性上比 MVC 模型好很多。

MVP 框架流程如图5所示:

MVP框架流程图
图5:MVP框架流程图

从图5中可以看出,View 层与 Model 层确实互不干涉,View 层也自由了很多。但还是有问题,因为 View 层和 Model 层都需经过 Presenter 层,致使 Presenter 层比较复杂,维护起来会有一定的问题。而且因为没有绑定数据,所有数据都需要 Presenter 层进行“手动同步”,代码量比较大,虽然比 MVC 模型好很多,但也是有比较多的冗余部分。

为了让 View 层和 Model 的数据始终保持一致,避免同步,MVVM 框架出现了。

3. MVVM 框架#

MVVM 最早是由微软在使用 Windows Presentation Foundation 和 SilverLight 时定义的,2005 年微软正式宣布 MVVM 的存在。VM 是 ViewModel 层,ViewModel 层把 Model 层和 View 层的数据同步自动化了,解决了 MVP 框架中数据同步比较麻烦的问题,不仅减轻了 ViewModel 层的压力,同时使得数据处理更加方便——只需告诉 View 层展示的数据是 Model 层中的哪一部分即可。

MVVM 框架如图6所示:

MVVM框架图
图6:MVVM 框架图

读者可能感觉 MVVM 的框架图与 MVP 的框架图相似,确实如此,两者都是从 View 层开始触发用户的操作,之后经过第三层,最后到达 Model 层。但是关键问题是这第三层的内容, ViewModel 层双向绑定了 View 层和 Model 层,因此,随着 View 层的数据变化,系统会自动修改 Model 层的数据,反之同理。而 Presenter 层是采用手动写方法来调用或者修改 View 层和 Model 层,两者孰优孰劣不言而喻。

MVVM 框架流程图如图7所示:

MVVM框架流程图
图7:MVVM 框架流程图

从图7可以看出,View 层和 Model 层之间数据的传递也经过了 ViewModel 层, ViewModel 层并没有对其进行“手动绑定”,不仅使速度有了一定的提高,代码量也减少很多,相比于 MVC 和 MVP,MVVM 有了长足的进步。

至于双向数据绑定,可以这样理解:双向数据绑定是一个模板引擎,它会根据数据的变化实时渲染。这种说法可能不是很恰当,但是很好理解,如图8所示。

数据绑定概念
图8:数据绑定概念

如图8所示,View 层和 Model 层之间的修改都会同步到对方。

MVVM 模型中数据绑定方法一般有以下3种:

  • 数据劫持
  • 发布-订阅模式
  • 脏值检查

Vue.js 使用的是数据劫持和发布-订阅模式两种方法。

首先来了解三个概念:

  • Observer:数据监听器
  • Compiler:指定解析器
  • Watcher:订阅者

Observer 用于监听数据变化,如果数据发生改变,不论是在 View 层还是 Model 层, Oberver 都会知道,然后告诉 Watcher。Compiler 的作用是对数据进行解析,之后绑定指定的事件,在这里主要用于更新视图。

Vue.js 数据绑定的流程:首先将需要绑定的数据用数据劫持方法找出来,之后用 Observer 监听这堆数据,如果数据发生变化,Observer 就会告诉 Watcher,然后 Watcher 会决定让哪个 Compiler 去做出相应的操作,这样就完成了数据的双向绑定。

4. MVC、MVP 和 MVVM三者的区别和优劣#

详细了解 MV 系列框架之后,相信读者已经了解 MVC、MVP、MVVM 这三者的优劣了。其实从 MVC 到 MVP 再到 MVVM,是一个不断进步的过程,后两者都是在 MVC 的基础上做的变化,使 MVC 更进一步,使用起来也更加方便。

MVC、MVP、MVVM 三者的主要区别就在于除 View 层和 Model 层之外的第三层,这一层的不同使得 MV 系列框架区分开来。

其实很难说出 MVC、MVP、MVVM 哪一个更好,从表面上看,显然是 MVVM 最好,使用起来更方便,代码相对也较少。但问题是 MVVM 的框架体积较大,相比于 MVC 的不用框架、MVP 的 4KB 框架,MVVM 遥遥领先。虽然 MVVM 框架可以单独引用,但现在更多使用前端脚手架工具进行开发,并且使用打包工具,这样一来,它跟 MVC 相比,体积是天差地别。

虽然机能过剩更令人放心,但是轻巧一些的框架会令项目锦上添花。所以要根据实际项目的需求来选择 MVC、MVP、MVVM,只有最适合的模式才是最好的框架。

MVC,MVP,MVVM 对比[2]#

Photo by [Edwin Andrade](https://unsplash.com/@theunsteady5?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)

当下有很多种设计模式可供我们选择。 在分别使用 Model-View-ViewModel (MVVM),Model-View-Presenter (MVP),和 Model-View-Controller (MVC),模式开发了一些 app 后,我觉得是时候聊聊它们间的区别了。为了方便理解,这里我们举一个例子:开发一个查找书籍的小功能,其实就是那些 BookSearch 应用中的搜索功能。

让我们开始吧

MV(X) 基本概念#

在深入研究 MVC,MVP 和 MVVM 架构之前,我们要简要的了解下它们。

为什么会诞生 Model-View-(C or P or VM)?#

最初这些架构的目的都是为了将带有图形界面的应用解构成各司其职的几块:视图,处理程序,数据管理。

separate the responsibilities of visualizing, processing, and data management

现在有了更多的目标

  • 模块化
  • 灵活性
  • 可测性
  • 可维护性

Model-View-Controller#

简称 MVC,它是架构软件应用程序的一种广泛使用的设计模式。该模式最初是由 Trygve Reenskaug 在从事 Smalltalk-80(1979)的工作期间设计的,最初被称为 Model-View-Controller-Editor。1994 年在 “设计模式 : 可复用面向对象软件的基础”(又名 “GoF”)一书中对 MVC 进行了更深入的描述,该书在推广其使用方面发挥了作用。 该模式将应用程序分为三个部分。

  • Model —— 负责应用的业务逻辑。它管理着应用的状态。这还包括读取和写入数据,持久化应用程序状态,甚至可能包括与数据管理相关的任务,例如网络和数据验证。
  • View —— 这部分有两个重要的任务:向用户展示数据和处理用户和应用的交互。
  • Controller —— view 层和 model 层经由一个或多个 controller 绑定在一起。

MVC on Android

Model–View–Presenter#

MVP 是 MVC 设计模式的衍生品,该模式专注于改进展示逻辑。它起源于 1990 年代初的一家名为 Taligent 的公司,当时他们正在开发一个运行于 C ++ CommonPoint 环境的模型。

虽然 MVP 是 MVC 的衍生品,但它们也有细微的差别。

  • Model —— model 代表一组描述业务逻辑和数据的类。它制定了更改和操作数据的规则。
  • View —— view 负责与用户进行交互,就如下图中 XML、Activity、fragments 部分。它与流程中要实现的逻辑无关。
  • Presenter —— presenter 从 View 获取输入,在 model 的帮助下处理数据,并在处理完成后将结果传递回 view。

MVP on Android

Model-View-ViewModel#

MVVM 最初是由 Microsoft 提出的,用于 Windows Presentation Foundation(WPF)和 Silverlight,由 John Grossman 于 2005 年在有关 Avalon(WPF的代号)的博客文章中正式提出。这种基于 MVC 和 MVP 的模式致力于将应用中 UI 的开发与业务逻辑的开发分离。

它由如下的三部分组成。

  • Model —— MVVM 中的 model 层和 MVC 中的 model 层非常相似,包含了供应用正常运转所需的基本数据。
  • View —— view 层是用户和设计模式之间的图形界面,类似于 MVC 中的 view 层。用来展示处理后的数据。
  • View-Model —— view-model 既是视图层的抽象,又提供了要访问的模型数据的包装。 也就是说,它包含一个可以被转换为视图的模型,并且还包含了一些命令,视图层可以使用这些命令更改模型。

MVVM on Android

MVC vs MVP vs MVVM#

让我们来看下 MVC、MVP 和 MVVM 间的主要区别。

性能上的评估 —— 当我们测试 UI 的性能时,就渲染帧而言,可以认为 MVP 是其中可靠性最高,阻塞最小的了。MVVM 中的数据绑定会产生额外的过载,很可能导致在执行复杂任务时性能严重下降。

兼容性 —— 当测试它们的兼容性时,MVVM 是其中最好的,这得益于它的数据绑定。MVP 的表现要好于 MVC,后者存在严重的重启问题。

拓展性 —— 说起设计模式,它们必须要有一定的拓展性,因此我们才可以在应用中不断添加新的功能和策略。

  • 由以上几点得知,MVP 和 MVVM 的区别较小,不过 MVVM 的可维护性略胜一筹。
  • 多数情况下,每次后续的拓展,采用 MVC 模式的应用需要改动更多的地方。

引用 —— 在 MVC 中,view 未直接引用 controller,而在 MVP 中,视图引用了 presenter,在 MVVM 中,view 引用了 view-model。

应用入口 —— 对于 MVC,应用程序的入口是 controller,而对于 MVP 和 MVVM,入口是 view。

使用不同的架构来完成上文的示例#

尝试使用如下的架构之一开发 BookSearch 应用,这有助于你对上文的理解。

MVC vs MVP vs MVVM implementation for the BookSearch application

很简单吧?你现在可以自个儿尝试实现一下。


  1. 1.链接找不到了
  2. 2.MVC vs MVP vs MVVM
点击查看
-------------------本文结束 感谢您的阅读-------------------