从MVC说起 - 概念(Version 1.0)
来源:互联网 发布:linux 运行sh脚本 编辑:程序博客网 时间:2024/06/03 10:19
MVC模式可能是被人们谈起最多的模式,但同时也可能是被误解最多的模式。MVC产生的背景是什么?MVC分别表示什么?它与MVP之间的关系是什么?类似的问题还有许多,在本文中,我们从MVC的起源开始探索一下它的前生今世,以试图回答这些问题。而在随后的文章中,我将从代码的角度回答这些问题。
MVC模式属于GUI模式,因此它的出现是为了解决GUI程序设计中的一些普通存在的问题,这些问题包括:
1. 谁负责与用户交互?
2. 谁负责处理视图逻辑?
3. 谁负责更新模型?
4. 模型发生改变后,谁负责更新视图?
5. M, V, C的作用范围?
概括起来就是说M, V, C的职责是什么?不同的模式对这些问题的回答具有很大的差异,这也正是令人混淆的原因所在。
1 经典MVC
大约在1978-1979年,Trygve Reenskaug第一次正式提出了MVC模式,它的前身是Thing-Model-View-Editor。后来此模式的一个变种作为Xerox PARC Smalltalk-80类库的一部分被实现,关于此实现的描述可以在Application Programming in Smalltalk-80(TM): How to use Model-View-Controller(MVC)中找到。经典MVC的结构如图1所示,其中右侧的结构图来自Aviad's Blog中一篇文章"Twisting the MVC Triad - MVP Design Pattern",形象生动的说明了MVC模式中各个组件的功能及作用范围。
图1 经典MVC模式
在经典MVC中,Controller负责拦截用户动作(即输入),视图负责显示数据(即输出),Controller和View可以直接修改Model,并且通过Model交互。View(和Controller)都观察Model,这样多个widget可以同步更新而不必相互通信。至于Controller和View之间的关联更多的是为了定位的目的。
需要注意的一个问题就是,每种模式的提出都是为了解决当时所面临的一些问题,就像评价历史人物一样我们需要站在人物所处的时代去研究他,MVC第一次提出是在70年代,它的主要目的是分离表示(Presentation)和领域模型(Domain Model),这也是它的核心所在,其后出现的各种变种也都是为了更好的分离表示和模式。只是由于后来的GUI环境已经发生了太多的变化,例如控件的出现使得控件本身就可以拦截用户动作,而在经典MVC中这是Controller的职责。M, V, C的作用范围也是一个很重要的区别。在经典MVC和Application Model MVC中,用户界面上的每一个Widget(小物件,类似于控件)都包含一个View和一个Controller,用户对Widget的动作由它包含的Controller拦截处理,但是随着控件的出现,控件本身已经可以拦截用户动作,因此最终导致了Controller的消失。
注意:本段使用的是拦截(intercept)而不是处理,意思是用户动作的处理可能会转交给其它对象,就像我们在MVP模式中看到的那样。
2 Application Model MVC模式
图2同样来自Avaid的博客,展示了Application Model MVC模式中各个组件的关系,职能。
图2 Application Model MVC模式
1980年前后,从Xerox Parc实验室分离(span off)出的ParcPlace ,负责Smalltalk的市场和开发,ParcPlace Smalltalk也称为Visual Works,在这个框架中引入了一个新的实体Application Model,它作为Model和View之间的协调者,负责视图逻辑(View Logic)。View和Controller不在依赖Model,转而依赖Application Model。
Application Model MVC 的一个亮点在于Application Model的引入,它与MVP模式中的Presenter有点类似,都负责视图逻辑,只是Application Model还不够彻底,不能直接访问View,而只能触发某些特殊的事件,让View监听这些事件并更新自己,这种处理视图的方式显得非常笨拙。除此以外,其它方面与经典MVC基本相似。
3 Talgent MVP
1996年,Mike Potel在他的论文,MVP: Model-View-Presenter The Ta nt Programming Model for C++ and Java,正式提出了MVP模式,结构如下图所示。
图3 Taligent MVP模式
Model指应用程序中的数据和业务功能。Selections指出操作的是Model中的哪些数据。Commands定义了数据可以执行的操作。View作为Model的可视化表示,它由应用程序界面中的Widgets组成。Interactors指出如何将用户事件映射到针对Model的操作,例如鼠标移动,键盘输入等。Presenter负责创建Model,Selections,Commands,Views和Interactors,并且控制应用程序的执行。
在这个模型中,Interactor类似于经典MVC中Controller,它负责拦截用户动作,但是如何处理用户动作是由Presenter决定的,它会对Model应用合适的Commands或/和Selections。Presenter的功能被大大的加强了,它的角色就好像是一个子系统的管理者。
另外,在Ta nt MVP中,抛弃了每个Widget都有一个View的做法,而是多个Widgets对应一个View,而且Presenter和View一般是一一对应的,或者一个Presenter管理多个Views。
4 Dophin Smalltalk MVP
图4 Dophine Smalltalk MVP
上图摘自论文Twisting The Triad The evolution of the Dolphin Smalltalk MVP application framework,从图中可以看出,Dophin Smalltalk MVP通过去掉了Selections,Commands和Interactors从而简化了Ta nt MVP。Dophin Smalltalk MVP与Ta nt MVP的主要区别体现在以下几个方面:
1. Presenter与View的关系更加紧密,Presenter可以直接修改View。
2. View中的Widget已经可以拦截大部分用户动作并处理其中的一部分。
3. 某些情况下,View可以直接更新Model,但是大多数情况下用户事件委托给Presenter处理。
MVP设计模式分离了视图和它的表现逻辑,允许它们独立的改变。View可以看作是widgets的联合体,它不包含任何描述widget如何响应用户交互的行为,widgets对应于Forms/Controls模型中的控件,并且view和controller联系在一起。
Widgets拦截用户动作,然后转交给Presenter处理,Presenter决定如何响应。当Potel讨论这种交互时主要使用术语actions on model,这是通过命令系统和selections系统完成的。
从MVC模式的演化可以看出,随着技术的发展,各个组件的职责发生了很大的变化。Controller完全消失了,这是因为随着View中Widget的功能越来越丰富,它承担了拦截用户动作和部分处理任务。View最初只是简单的呈现模型,现在它已经囊括了Controller的职能,并且有时候可以直接操作Model(当然不提倡这样做,因为这涉及到可测试性的问题)。Presenter从无到有,承担着更新模型和视图的任务,虽然应用数据绑定技术和观察者模式可以很好的同步Model和View,但是由于图形用户界面越来越丰富,交互性越来越强,这就需要更好的协调Presenter和View来创造更好的用户体验,我们可以从Presenter和View的关系越来越紧密窥见一斑。
5 Suptervising Controller和Passive View
在2006年,Martin Fowler将MVP模式分为两个模式,分别命名为Supervising Controller和Passive View。这种区分主要是围绕着Presenter/Controller组件承担表现层逻辑的深度进行的。
注意:这里的Controller与经典MVC中的Controller概念不同,在经典MVC中,Controller主要负责处理用户动作,而Suptervising Controller或Passive View中的Controller实际上相当于MVP模式中的Presenter。作用范围也不一样,在经典MVC中,用户界面中的每一个控件都有自己的Controller和View,Controller只负责处理它所在的控件的用户动作,而Suptervising Controller或Passive View中,Controller和View都是屏幕级别的。
5.1 Suptervising Controller模式
下面这幅图描述了Suptervising Controller模式的结构
图5 Suptervising Controller模式
Suptervising Controller负责响应来自View的用户输入和处理复杂的表现逻辑,View负责Model呈现和一些简单的表现逻辑。简单表现逻辑特指那些利用数据绑定技术或Observer模式就可以轻松解决的问题。
5.2 Passive View
Passive View模式的结构图如下所示:
图6 Passive View模式
Passive View模式与Supervising Controller模式最大的区别在于View与Model没有关联,完全依赖Controller执行所有的表现层逻辑。这种结构的可测试性最强,但是需要编写较多的表现层逻辑代码。
至于选择Passive View模式还是Supervising Controller模式,很大程度上取决于个人的喜好,与Passive View模式相比,Supervising Controller模式比较灵活,对于简单的表现逻辑使用数据绑定技术,通过声明式的编程方式,View可以随着Model的改变而改变,
总的来说,MVC模型的演化过程就是职责重新分配的过程,决定这个过程的关键因素是软件技术的发展(控件,数据绑定,模式等),和软件工程思想的发展(可测试性,可维护性等)以及用户体验。
参考文献:
1. GUI Architeture, Martin Flower
2. Twisting The Triad The evolution of the Dolphin Smalltalk MVP Application Framework, Andy Bower, Blair McGlashan
3. MVP: Model-View-Presenter The Ta nt Programming Model for C++ and Java, Mike Potel
4. Twisting the MVC Triad - MVP Design Pattern
5. Interactive Application Architecture Patterns
6. MVC WiKi
后记:
在阅读了多篇关于MVC和MVP模式论文之后,试着总结了其中的一些要点,并添加了自己的一些理解之后写成本文。其中关于M、V、C或者P的职责解释不一定全面透彻,不过基本意思应该是正确的。考虑到MVP模式在GUI编程中的重要性,建议使用一种MVC框架,使用前需要了解框架的结构。
中文有各种各样的输入法可以帮助我们快速输入中文,不知道英文有没有英文输入法?
Powered by Zoundry
http://blog.csdn.net/dreamliner/article/details/2643538
- 从MVC说起 - 概念(Version 1.0)
- 从MVC说起 - 概念(Version 1.0)
- Spring MVC 简述:从MVC框架普遍关注的问题说起
- Spring MVC 简述:从MVC框架普遍关注的问题说起
- Spring MVC简述:从MVC框架普遍关注的问题说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 从PowerDesigner概念设计模型(CDM)中的3种实体关系说起
- 系统调用
- 知识管理七种武器之内容管理系统-ECM
- C++类模板实现顺序表
- ubuntu下嵌入式开发环境的设置
- 杂记
- 从MVC说起 - 概念(Version 1.0)
- 甲骨文位列Gartner ECM领导者象限
- ☆逆序对 动态规划+高精度
- 修正Ok6410的U-Boot网络不可用
- (7)中断概述
- s3c-nand: ECC uncorrectable error detected
- C++类模板实现双链表
- 2.3 AndroidMainfest.xml与应用程序功能组件
- 探讨:选择内容管理平台还是解决方案?