MVC

MVC

在整个 GUI 编程领域,MVC 已经拥有将近 50 年的历史了。早在几十年前,Smalltalk-76 就对 MVC 架构模式进行了实现,在随后的几十年历史中,MVC 产生了很多的变种,例如:HMVC、MVA、MVP、MVVM 和其它将 MVC 运用于其它不同领域的模式。

早期的 MVC

而本文的内容就是从 MVC 开始的,作为最出名并且应用最广泛的架构模式,MVC 并没有一个明确的定义,网上流传的 MVC 架构图也是形态各异,作者查阅了很多资料也没有办法确定到底什么样的架构图才是标准的 MVC 实现。

MVC-1979

设计 MVC 的重要目的就是在人的心智模型与计算机的模型之间建立一个桥梁,而 MVC 能够解决这一问题并为用户提供直接看到信息和操作信息的功能

更早的概念类似 Model-View-Editor(MVE)这里就不再提及了,感兴趣的读者可以阅读这篇论文 Thing-Model-View-Editor 了解更多的信息。

混乱的 MVC 架构

作者相信,稍有编程经验的开发者就对 MVC 有所了解,至少也是听过 MVC 的名字。作者也一直都认为绝大多数人对于 MVC 理解的概念都一样,很多人对于 MVVM 的实现有很大争论,说遵循什么什么架构的是 MVVM,MVVM 有什么组件、没有什么组件,而对于 MVC 仿佛没有那么大的疑问,这其实却不然。

ASP.NET MVC

在最近的几个月,作者发现不同人对于 MVC 的理解有巨大的差异,这是 ASP.NET MVC Overview 一文中对于 MVC 模式描述的示意图。

MVC-with-ASP.NET

图片中并没有对 Model、View 和 Controller 三者之间如何交互进行说明,有的也只是几个箭头。我们应该可以这么简单地理解:

  1. 控制器负责管理视图和模型;
  2. 视图负责展示模型中的内容;

由于文章没有明确对这三个箭头的含义进行解释,所以在这里也仅作推断,无法确认原作者的意思。

Spring MVC

与 ASP.NET 不同,Spring MVC 对于 MVC 架构模式的实现就更加复杂了,增加了一个用于分发请求、管理视图的 DispatchServlet:

MVC-with-Spring

在这里不再介绍 Spring MVC 对于 HTTP 请求的处理流程,我们对其中 Model、View 和 Controller 之间的关系进行简单的分析:

  1. 通过 DispatchServlet 将控制器层和视图层完全解耦;
  2. 视图层和模型层之间没有直接关系,只有间接关系,通过控制器对模型进行查询、返回给 DispatchServlet 后再传递至视图层;

虽然 Spring MVC 也声称自己遵循 MVC 架构模式,但是这里的 MVC 架构模式和 ASP.NET 中却有很大的不同。

iOS MVC

iOS 客户端中的 Cocoa Touch 自古以来就遵循 MVC 架构模式,不过 Cocoa Touch 中的 MVC 与 ASP.NET 和 Spring 中的 MVC 截然不同。

MVC-with-iOS

在 iOS 中,由于 UIViewController 类持有一个根视图 UIView,所以视图层与控制器层是紧密耦合在一起的,这也是 iOS 项目经常遇到视图控制器非常臃肿的重要原因之一。

Rails MVC

Rails 作为著名的 MVC 框架,视图层和模型层没有直接的耦合,而是通过控制器作为中间人对信息进行传递:

MVC-with-Rails

这种 MVC 的设计分离了视图层和模型层之间的耦合,作为承担数据存储功能的模型层,可以通过控制器同时为多种不同的视图提供数据:

MVC-in-Rails-with-different-view

控制器根据用户发出的 HTTP 请求,从模型中取出相同的数据,然后传给不同的视图以渲染出不同的结果。Rails 中的 MVC 架构模式能够很好地将用于展示的视图和用于存储数据的数据库进行分离,两者之间通过控制器解耦,能够实现同一数据库对应多种视图的架构。

维基百科中的 MVC

除了上述框架中的 MVC 架构模式,还有一些其它的书籍或者资料对于 MVC 也有着不同的解释,比如维基百科的 Model-view-controller 条目,该条目是我们在 Google 搜索 MVC 时能够出现的前几个条目,这也是维基百科中的架构图能够出现在这篇文章中的原因 —— 有着广泛的受众。

MVC-in-Wikipedia

维基百科中对于 MVC 架构模式交互图的描述其实相比上面的图片还都是比较清晰的,这主要是因为它对架构图中的箭头进行了详细的说明,指出了这个关系到底表示什么。

  1. 视图被用户看到;
  2. 用户使用控制器;
  3. 控制器操作模型;
  4. 模型更新视图;

虽然说整个架构图的逻辑是可以说的通的,不过相比于前面的架构图总是感觉有一些奇怪,而在这幅图片中,视图和控制器之间是毫无关系的,

这与前面见到的所有 MVC 架构模式都完全不同,作者也不清楚这幅图来源是什么、为什么这么画,放在这里也仅作参考。

『标准』的 MVC

到底什么才是标准的 MVC 这个问题,到现在作者也没有一个确切的答案;不过多个框架以及书籍对 MVC 的理解有一点是完全相同的,

也就是它们都将整个应用分成 Model、View 和 Controller 三个部分,而这些组成部分其实也有着几乎相同的职责。

  • 视图:管理作为位图展示到屏幕上的图形和文字输出;
  • 控制器:翻译用户的输入并依照用户的输入操作模型和视图;
  • 模型:管理应用的行为和数据,响应数据请求(经常来自视图)和更新状态的指令(经常来自控制器);

上述内容出自 Applications Programming in Smalltalk-80: How to use Model-View-Controller (MVC) 一文。

作者所理解的真正 MVC 架构模式其实与 ASP.NET 中对于 MVC 的设计完全相同:

Standard-MV

控制器负责对模型中的数据进行更新,而视图向模型中请求数据;当有用户的行为触发操作时,会有控制器更新模型,并通知视图进行更新,

在这时视图向模型请求新的数据,而这就是作者所理解的标准 MVC 模式下,Model、View 和 Controller 之间的协作方式。

依赖关系

虽然我们对 MVC 中的各个模块的交互不是特别了解,但是三者之间的依赖关系却是非常明确的;

在 MVC 中,模型层可以单独工作,而视图层和控制器层都依赖与模型层中的数据。

 

Essential-Dependencies-in-MVC

虽然如上图所示,视图和控制器之间没有相互依赖,不过因为视图和控制器之间的依赖并不常用,

所以图中将视图和控制器之间的依赖省略了。

 

 

https://draveness.me/mvx/

posted @ 2020-04-27 07:23  钢与铁  阅读(471)  评论(0编辑  收藏  举报