在MVC结构中,模型(Model)代表应用程序的数据(data)和用于控制访问和修改这些数据的业务规则(business rule)。通常模型被用来作为对现实世界中一个处理过程的软件近似,当定义一个模型时,可以采用一般的简单的建模技术。
当模型发生改变时,它会通知视(View),并且为视提供查询模型相关状态的能力。同时,它也为控制器(Controller)提供访问封装在模型内部的应用程序功能的能力。
一个视(View)用来组织模型的内容。它从模型那里获得数据并指定这些数据如何表现。当模型变化时,视负责维持数据表现的一致性。视同时将用户要求告知控制器(Controller)。
同样的数据,可以有不同的显示和进行各种处理。显示仅仅是表现数据,而处理是根据用户请求改变数据的过程,不但包含业务逻辑,也要提供响应策略。响应策略 由控制器负责,视图可以使用不同的控制器提供不同的响应方式,这是策略(Strategy)模式的应用。
此外,MVC还允许视图嵌套,通过使用组合(Composite)模式,一致地处理组合视图和普通视图。
用多个视图表现一个模型,在视图不变的情况下改变响应策略,允许视图嵌套,这是MVC的三个主要特性。在内部结构上,MVC的主要关系是由观察者模 式,策略模式和组合模式给出的。由观察者模式确定的模型视图关系是其中最为重要的。
MVC 模式有许多变体。前述结构中,由模型通知视图刷新,称为主动MVC;如果由控制器更新模型以后通知视图,称为被动MVC结构。在许多应用中,没有明显的控 制器角色,也没有视图嵌套。可见根据实际需要,构成MVC的三个模式上都可能出现变化。
• |
模型。模型用于管理应用程序域的行为和数据,并响应为获取其状态信息(通常来自视图)而发出的请求,还会响应更改状态的指令(通常来自控制器)。 |
• |
视图。视图用于管理信息的显示。 |
• |
控制器。控制器用于解释用户的鼠标和键盘输入,以通知模型和/或视图进行相应的更改。 |
图 1 描述了这三个对象之间的结构关系。
图 1:MVC 类结构
请务必注意,视图和控制器都依赖于模型。但是,模型既不依赖于视图,也不依赖于控制器。这是分离的主要优点之一。这样的分离允许模型在独立于可视表示功能的情况下建立和测试。在许多胖客户端应用程序中,视图与控制器的分离是次要的,实际上,许多用户界面框架将角色实现为一个对象。另一方面,在 Web 应用程序中,视图(浏览器)与控制器(处理 HTTP 请求的服务器端组件)的分离是很好定义的。
Model-View-Controller 是一个用于将用户界面逻辑与业务逻辑分离开来的基础设计模式。遗憾的是,此模式的普及导致了许多错误的描述。特别是在不同的上下文中,术语"控制器"已经用于意指不同的事物。幸运的是,Web 应用程序的出现已经帮助消除了一些不明确性,因为视图与控制器的分离是如此明显。
变型
在 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:主动模型的行为
http://blog.csdn.net/lee576/article/details/1732353