关键要点
MVC已成为每一代软件开发人员所最早接触到的软件开发原则之一。
MVC应被视为一种通用的架构原则和方法。
MVC三元组件的语义随架构环境的不同而变化。
可将基于HTTP的Web MVC(WMVC)分成三个不同的类别:sWMVC、dWMVC和pWMVC。
随着近期技术的进步,异步且实时观察变化的“事件循环”可用于WMVC应用的实现。
引言
MVC( 模型-视图-控制器 ,Model-View-Controller)最初用于设计和实现狭义的桌面图形用户界面(GUI)应用开发。经典的MVC与面向对象的程序开发方法一样,已成为每一代软件开发人员所最早接触到的软件开发原则之一。虽然MVC对当今的工业界有着如此重要的影响,但是在日益互联计算的时代,很明显MVC的内涵已 迷失了其精准性 。这在过去20年间对于WUI(Web图形界面,Web Graphical Interface)开发领域尤其是如此。基于以上原因,本文意在对MVC的起源做概要地阐述之后,进而深入地探讨基于Web的MVC的演进和变化。
在WUI的应用场景下,原始MVC及MVC三元组中成员对象的历史意义和内涵在不断地演变和转变形态。出于消除任何概念上的混淆的考虑,在本文的探讨中将使用“WMVC”一词表示基于Web的MVC式架构模式。大多数技术平台的WMVC特性正处于不断地改进之中,这包括Microsoft的 ASP.NET MVC 、PHP的 Symfony 、Python的 Django 、Ruby的 Merb 、Java的 JSR 371 等。驱动这些平台改进的原则,很大程度上在于JavaScript已可由客户端浏览器运行。此外,不少新的网络协议充实了服务器-客户间的通信。
自JavaScript被 XMLHttpRequest 赋予新生以来,它就成为WUI开发中情有独钟的技术。在过去的数年内,就有超过二十种 基于WMVC的JavaScript应用萌芽发展,其中包括 Dojo 、 Angular 、 Ember 、 Backbone 和 React 等。即使不是全部的也是绝大部分的框架都是侧重于客户端组件的交互,对于WMVC视图和控制器的组成对象而言尤其是如此。自然而言,WUI开发方法上的革新再一次引发了针对MVC亦或WMVC的大量讨论。这些讨论时常是十分激烈的,通常侧重于某个特定的方面,或基于某个特定的环境。进而使得MVC(WMVC)衍生出一些主要差异在于控制器对象的变体,其中包括 MVA 、 MVP 、 MVVM 、 Flux 、 Redux 和SAM等。这些MVC变体时常被统称为“MV*”,其中的“*”表示了各变体间的差异主要在于视图和控制器间的交互方式。通常并不将表示现实世界视图对象的模型组件整体地列入考虑中,或仅是在Web应用方案中将模型作为MVC三元组关系里的被动参与者。
自MVC概念于四十多年前被提出以来,MVC模型很有可能已经历了最重要的改变。在本文的探讨中,我们对MVC模型做了一个宽泛的定义,这个定义中涵盖了驻留内存的模型对象(例如 记录集对象 ),还有用于支撑对象的 SoR (主数据记录系统,System of Record)中的源数据、源文档、源文件和原始信号,以及所有把它们同步和聚集到一起的过程。模型数据仓库的存储形式已从小型 软盘 发展到 RDBMS 和MMDBMS (多模数据库管理系统,multi-model database management system)。早期模型数据仓库是与驻留内存的模型对象共处一处的,这些模型对象是独立存在于各个用户桌面之上的。现在模型数据仓库使用宽带连接、分布式或基于云的系统,其部署可远离域对象。存储在这种外部环境中的数据,可以被企业生态系统的多个系统修改,也可以被消费者应用的数以千计的用户修改。这种使用场景上的根本差异,已经在根本上地改变了模型对象的行为,进而改变了模型对象与MVC三元组中的另两个成员间的通信和交互。
原型MVC
oMVC (原型MVC,Original MVC)是由挪威计算机科学家Trygve Reenskaug于1978年 提出 ,当时他工作于著名的 Xerox PARC 研究中心 Smalltalk 团队中。在oMVC的概念初步成型后,最初被实现为 Smalltalk-80类库 的一部分,用于桌面GUI的建立。
在那个时代,桌面应用远非当前这样是日常家居中的常见物品,每个应用需要独立运行于一台机器上,而每台机器的存储是有限的并且是各自独立的。正如在图1中所示,对oMVC模型对象的任何操作都完全由用户行为通过控制器所触发,MVC三元组在受控的环境中进行通信、同步并保持状态。控制器的主要作用是维持用户和系统之间的联系(参见图1)。控制器实现对相关GUI组件的部署,并在屏幕上将这些GUI组件展现给用户。在 Win95出现之前 的年代中,这是一个具有挑战性的任务,因为当时MS-DOS 依然是占据主要地位的操作系统。在oMVC模型中,一旦用户产生了某种动作,例如菜单选取、在输入框中输入、按钮点击等,控制器就会转化这些动作为对应的改变消息,向模型传递这些消息,并对消息进行处理。