图1展示了独立桌面环境中的oMVC。图中显示了作为模型的组成部分的本地软盘数据存储。oMVC中控制器和视图具有成对出现的关系,但是模型的改变并不在两者间直接产生通信。控制器和视图知道模型的状态,但是反之并非如此。
一旦模型从控制器获取了变更通知,它并不直接通过调用去更新所涉及的视图。在模型-视图的关系中,变更通知的获取是通过每个独立的参与者之间的相互注册实现。一旦一方发生了变更,就会生成一个事件,对方就会采取相应的动作作为响应。在图1中,视图是附属于模型的,对模型进行观察。一旦控制器触发了模型变更事件,视图必须去确保自身显示也按需更新,以相应地反映出模型的状态。更新模型的通知信号也可由视图自身生成。这种视图与模型之间的 观察 (或订阅)和通知关系,有助于模型和视图间的解耦,使得多个视图可隶属于同一模型,进而可提供不同的表示。
在图1中值得注意的是,控制器并非直接地改变视图。在Smalltalk社区及其它后续的桌面GUI应用库中,通常将视图和控制器看成一对耦合的对象。视图使用具有特定控制器类型的实例实现预期的响应。为创建所期望的行为,控制器还可以在不同情景中 策略性地 、动态地切换类型。这样的视图-控制器对可以嵌套于 复合 层次结构中(如图2A所示)。在该层次结构中的父辈之间、子女之间及父子之间,视图-控制器组件都可以进行交互和通信。很多情况下,层次结构中的每个独立视图-控制器的子女组件仅处理部分的模型对象。此外,从oMVC组合的角度看,模型也可以使用层次结构的形式进行组织,这样 MVC三元组作为一个整体 构成 层次结构中的父子关系 ,如图2B所示。
(点击放大图像)
图2左图是oMVC的复合表示,右图是 PAC (显示-抽象-控制,Presentation-Abstraction-Control)的表示。
总而言之,oMVC设计范例是由一系列的 GoF设计模式 所组成,尤其是其中包括了观察者模式 、 策略模式 和 复合模式 。在早期的桌面应用库中,oMVC域架构和模式的设计意图得以保持,即模型组件由应用域对象和数据存储所组成,其中存储多是本地的或是受限的。在oMVC三元组类的行为中,应用域行为的维护和广播起着核心的作用。oMVC的一个关键假设是模型的稳定性,该假设在上世纪七十和八十年代的桌面应用情景中显然是正确的。但是在WMVC领域,模型时常发生改变通常是一种常态。直至近些年,向用户实时广播变更(类似于oMVC所实现的)所需的技术基础才得以实现。
WMVC的分类
具有讽刺意味的是,虽然直到上世纪九十年代,尤其是在Win95出现之后的年代,桌面计算机开始进入普通百姓家并得到普及,但是传统的桌面应用却因为因特网互联的Web应用开始统治了业界而逐渐退居幕后。不同于安装并于运行于终端用户计算机上的桌面应用,Web应用是宿主于远离用户的服务器上,创建了客户-服务器的关系。在本文的其后内容中,我们将浏览器(browser)和客户(client)这两个概念互换使用。根据浏览器和服务器相对于WMVC三元组对象的部署位置和执行方式的不同,可将WMVC明确地分组为:
服务器端WMVC (Server-side WMVC,sWMVC):所有WMVC的组件位于服务器上,并在服务器上执行。
双重WMVC(Dual WMVC,dWMVC):WMVC组件分布于浏览器和服务器之间。通信可由客户或者服务器端发起。
点对点WMVC(Peer-to-Peer WMVC,pWMVC):这种架构中没有集中式服务器。所有WMVC组件位于客户端,在客户端执行。pWMVC可具有自己的沙箱SoR。
服务器端WMV(sWMVC)
在sWMVC模型中,用户使用浏览器作为瘦客户,通过无状态的请求-响应HTTP协议访问应用(如图3所示)。客户向服务器发送HTTP请求或输入内容,接收并显示整个更新的Web页面(或是其它的文档)。一旦页面被加载以后,各页面组件间就很少有交互了,页面成为静止的。
在这种瘦客户-服务器范式的sWMVC架构中,应用SoR版本库外部化为一种集中式环境。它与应用服务器内存中的域对象是相互分离的。服务器和数据版本库都是远离用户浏览器部署的(如图3所示)。SoR存储常常是由一个或多个关系数据库这样的数据源所组成。鉴于数据已经外部化了,带外进程或不同的用户都可对数据进行更新。数据的变更只会从控制器流向模型(参见图3);当SoR中数据被不同的用户或系统改变时,并不向应用服务器发送入站数据变更通知。不同于oMVC,模型及其所关联的视图间不再有任何的直接联系和必要的同步。由于视图不再反映模型的状态,这就需要用户手动地发起新的HTTP请求去同步和刷新视图。因此sWMC中的“s”,也可指代这种WMVC范例的静态(static)或是陈旧(stale)的本质特性。