学习Design Pattern(设计模式)不是为了搞学术研究更不是装B,主要还是我有点洁癖:面对越来越复杂的ActionScript开发(主要是网站,还不包括Flex),我希望找点理论依据来做下指导,不仅把开发思路整理地井井有条,也可以更合理的分工协作。在我看来设计模式就是针对写代码中通常会遇见的情况而给出的指导性方法。遵循设计模式而写的代码最大的好处就是很直观,逻辑很清晰。当然还具有易扩展、易测试、可重用等等等等好处。本文大多数是这几年的开发经验有感而发,不是很严谨的学术文章,如有错误疏漏之处,请多包涵。
今天要谈的设计模式是在GUI程序设计中最常见的模式之一:MVC。在我2004年写论文的时候,曾把MVC模式和Web开发中的三层结构的概念混为一谈,直到今天才发现一直是我的理解错误。MVC模式是GUI界面开发的指导模式,基于表现层分离的思想把程序分为三大部分:Model-View-Controller,呈三角形结构(如下图)。Model是指数据以及应用程序逻辑,View是指Model的视图,也就是用户界面。这两者都很好理解,关键点在于Controller的角色以及三者之间的关系(也就是图中的那几个箭头)。

在MVC模式中,Controller和View同属于表现层,通常成对出现。Controller被设计为处理用户交互的逻辑。一个通常的误解是认为Controller负责处理View和Model的交互,而实际上View和Model之间是可以直接通信的。由于用户的交互通常会涉及到Model的改变和View的更新,所以这些可以认为是Controller的副作用。认清模式设计的目的对于帮助区分后来的MVP模式非常重要。
再来看看MVC架构图中的一条虚线。出于Model需要与View保持同步的基本需求,最初设计的时候这条也是实线,表示Model和View是紧密耦合的。但是实际开发中View通常都不是唯一的,为了适应一个Model对应多个View的情况,引入了Observer模式(在ActionScript开发中可以认为是事件机制)。在这种模式下,Model并不需要知道有多少View的存在,View观察/监听Model发生的改变并作出对应的更新。有兴趣的朋友可以看看关于这两种同步方式的描述:Flow Synchronization与Observer Synchronization。
MVC模式出现在1978-1979年间,当时的用户交互还很简单。随着计算机图形界面的发展,用户界面越来越复杂,开始包含更多的显示逻辑。比如很多开发工具支持数据绑定,事件绑定等等特性,一些对用户交互的处理已经封装到组件中去了。所以为了适应这些转变,MVC模式也出现了很多变体,其中最著名的就是Dolphin Smalltalk的MVP(Model-View-Presenter)模式。

我们可以对比上图与MVC模式的结构,好像仅仅是把Controller换成了Presenter。这可不是在玩文字游戏。在MVP中,Persenter被设计为包含表现层逻辑的单元。与Controller相对的是,Presenter主要是负责表现逻辑,处理用户交互变成了附带的功能。主要设计的目的的不同决定了模式的不同。
其实MVC发展到今天,Controller早已是Presenter的内涵,但开发者们习惯上还是都用Controller来描述。
2006年,Martin Fowler把MVP模式细分为两种表现层模式(Presetation Pattern):Supervising Controller和Passive View。

Supervising Controller

Passive View
Model-View-Controller三者之间的明暗对比关系说明了表现层在MVC模式中所处的位置。Supervising Controller和Passive View之间的区别在于后者完全切断了View和Model之间的联系,使得Controller变为View的代理。如果需要数据绑定等特性支持,或者考虑把一些简单的交互逻辑放在View中,就属于Supervising Controller模式。
此外,还有几种模式也属于表现层模式:Presentation Model、View Helper、Code Behind。其中只有Code Behind模式是用继承的方式实现的,Flash IDE下的文档类和类绑定就是属于这一种。几种模式的区别主要是以下几点:
- View和Presenter/Controller是否存在相互引用
- 状态保存在哪里
- 逻辑保存在哪里
- 单元测试是否容易进行
相对而言,用复合方式实现的模式灵活性较高一些。具体细节可以去这里看详细介绍,这里就不细述了。
本文主要总结了MVC/MVP模式中三者的概念区分,以及它们的联系。下一篇中我们就通过几个流行的ActionScript MVC框架来学习MVC模式中另一个重要的知识点:如何实现三者之间的联系——基于单例、注册模式或者依赖注入。
参考资料:
« 那些正在发生的事 Design Pattern #2 – Singleton, Registry & Dependency Injection »













好文,正在学习这部分的知识,请问还有相关内容的中文资料么?
网上中文的资料比较少,不过你可以去买本设计模式的书籍来看看。
好文,原先我也不理解C,单纯当成事件来理解。