| | | | | | | [文章信息] | | | 作者: | 微软架构与模式小组 | | 时间: | 2004-04-26 | | 出处: | MSDN开发精选 | | 责任编辑: | 方舟 | |
| [文章导读] | | | 本文描述了MVC模式的架构、设计及其ASP.NET实现,同时介绍了Web表示模式集群的另外两个模式:筛选器和页面缓存模式 | |
| |
|
| | | |
|
|
|
|
|
MVC解决方案
Model-View-Controller (MVC)模式基于用户输入,将域的建模、显示和操作分为三个独立的类[Burbeck92]:
模型。模型用于管理应用程序域的行为和数据,并响应为获取其状态信息(通常来自视图)而发出的请求,还会响应更改状态的指令(通常来自控制器)。
视图。视图用于管理信息的显示。
控制器。控制器用于解释用户的鼠标和键盘输入,以通知模型和/或视图进行相应的更改。
 图1、描述了这三个对象之间的结构关系
视图和控制器都依赖于模型。但是,模型既不依赖于视图,也不依赖于控制器。这是分离的主要优点之一。这样的分离允许模型在独立于可视表示功能的情况下建立和测试。在许多胖客户端应用程序中,视图与控制器的分离是次要的,实际上,许多用户界面框架将角色实现为一个对象。另一方面,在Web应用程序中,视图(浏览器)与控制器(处理HTTP请求的服务器端组件)的分离是很好定义的。
Model-View-Controller是一个用于将用户界面逻辑与业务逻辑分离开来的基础设计模式。遗憾的是,此模式的普及导致了许多错误的描述。特别是在不同的上下文中,术语“控制器”已经用于意指不同的事物。幸运的是,Web应用程序的出现已经帮助消除了一些不明确性,因为视图与控制器的分离是如此明显。
MVC的变型
在Application Programming in Smalltalk-80: How to use Model-View-Controller (MVC) [Burbeck92]中,Steve Burbeck描述了MVC的两个变型:被动模型和主动模型。
当一个控制器以独占方式操作模型时,将使用被动模型。控制器将修改模型,然后通知视图:模型已经更改,应该进行刷新(见图2)。此情况下的模型完全独立于视图和控制器,这意味着模型无法报告其状态更改。HTTP协议是此方案的示例。浏览器没有从服务器获取异步更新的简单方法。浏览器显示视图并对用户输入作出响应,但是它不会检测服务器上的数据更改。仅当用户显式请求刷新时,才会询问服务器是否发生了更改。
 图2、被动模型的行为
当模型更改状态而不涉及控制器时,将使用主动模型。当其他资源正在更改数据并且更改必须反映在视图中时,可能会发生这种情况。以股票报价机的显示为例。您从外部源接收股票数据,并希望当股票数据更改时更新视图(例如,报价机数据区和警告窗口)。因为只有模型检测对其内部状态的更改(在这些更改发生时),所以模型必须通知视图刷新显示。
但是,使用MVC模式的一个目的是使模型独立于视图。如果模型必须将更改通知视图,则会重新带来您希望避免的依赖性。幸运的是,Observer模式[Gamma95]提供了这样的机制:提醒其他对象注意状态的更改,而不会导致对这些对象的依赖性。各个视图实现Observer接口,并向模型注册。模型将跟踪由订阅更改的所有观察器组成的列表。当模型发生改变时,模型将会遍历所有已注册的观察器,并将更改通知它们。此方法通常称为“发布-订阅”。模型从不需要有关任何视图的特定信息。实际上,在需要将模型更改通知控制器的情况下(例如,启用或禁用菜单选项),控制器必须做的全部工作是实现Observer接口并订阅模型更改。对于存在许多视图的情况,定义多个主体是有意义的,其中每个主体都描述了特定类型的模型更改。然后,每个视图都只能订阅与视图有关的更改类型。图3显示了使用Observer的主动MVC的结构,以及观察器如何将模型与直接引用视图隔离开来。
 图3、在主动模型中使用观察器将模型与视图分离
图4说明当模型发生改变时Observer如何通知视图。可惜的是,在统一建模语言(UML)序列图中,没有好的方法来演示模型与视图的分离,因为该图表示的是对象的实例而不是类和接口。
 图4、主动模型的行为
|
|
|
|
|
|
|
|