在MVC模式的具体实现中,另一个令人困扰的问题就是:如何处理各个对象之间的依赖关系。
Ricard Lord在Flex London User Group上的演讲清楚的描述了这个问题。
在DI(Dependency Injection 依赖注入)还没有被引入ActionScript框架开发中的年代,处理依赖关系的方法主要就是利用Singleton(单例)模式。这是一种被滥用得最多的模式。包括Adobe官方的MVC框架Cairngorm也是使用这种模式。
后来的PureMVC采用了Registry Pattern / Model Locator Pattern来代替单例,但是也没能从根本上解决问题。类中包含了冗余的代码去获取依赖,也使得单元测试变得困难。
ActionScript 3新增的反射机制让DI模式的实现成为可能,也让ActionScript开发框架的发展更接近于Java等成熟语言。Mate、Swiz、Parsley和后面要介绍的Robotlegs都使用了DI模式。
其实不论是Singleton,Registry还是DI,都是要解决OOP中的依赖问题。但只有DI模式通过语言的反射机制实现了运行时注入的功能,从而将编译时依赖转移到了运行时。
当前最流行的开发框架是Robotlegs,它在PureMVC的基础上修改而来,被业内誉为“正确的PureMVC”。Robotlegs通过SwiftSuspenders类库实现了基于自定义元数据(meta)的依赖注入功能,建立了MVCS(Model-View-Controller-Service)模式的基本构架。作者Shaun Smith在这篇文章中详述了框架设计背后的思想。
上篇文章介绍MVC基本概念的时候提到用Observer模式来实现松耦合。在上述几个ActionScript框架中,都用不同的方式实现了系统事件发送类的单例(Single Event Dispatcher):通过一个统一的事件发送者在MVC架构中的对象之间传递信息。
但是,由于ActionScript的事件机制并不完美,所以最近业内又开始流行使用Robert Penner开发的代替方案AS3 Signals。我曾经做过一番尝试:可以告别编写事件名常量和自定义事件的繁琐,可以将事件写入接口等特性给人的感觉果然比较直观。所以如果将来Robotlegs能够在事件机制上整合Signals那就更好了,比如这个。
至此MVC模式的介绍就告一段落,总结来说:MVC把GUI程序划分为Model Layer和Presetation Layer,设计了Model-View-Controller三大模块的职责和关联方式。在表现层根据不同的耦合关系又细分多种模式。MVC现在的发展趋势是用DI、Observer模式等方法来实现模块之间的松耦合。
最后一点题外话,Ricard Lord的演讲还提到了Framework和Toolkit的区别,主要就是是否需要继承框架里的基类。Toolkit比较灵活,无需更改对象的继承关系。Robotlegs就属于这种,所以已经有出现把Robotlegs和Gaia Framework结合在一起的尝试。















