PureMVC(AS3)剖析:吐槽
写在前面 |
世上没有银弹——不存在适用于所有情况的框架,只有适合的框架。再者任何一个好的东西(语言、框架等)最终还取决于用的人,语言和框架本身并不能保证用户的代码清晰、解耦等,当然它只是尽可能地做到这点。所以记住我写这篇不是为了否定PureMVC,相反是为了更好的了解它、使用它。
1. 吐槽一:过于强调解耦
PureMVC引入了多种设计模式、消息机制(使用观察者模式,发布/订阅模式)来解耦各个模块,它确实做到了这点,但是彻底解耦是需要代价的!
1.1. Notification消息命名及管理复杂
PureMVC为了做到跨平台,使用Notification来实现模块间通信,而非Flash原生的EventDispatcher/Event机制。然而Notification使用字符串来定义消息,存在以下“问题”。
注:Notification并不是Event的替代物。一般情况下,Mediator给其视图组件添加Event侦听器,按常用方式处理,然后给目标Command/Mediator广播Notification。
n 消息ID为字符串,虽然字符串可以做到编译时解耦,但无法做到消息强类型,这样错误将推迟到运行时才能发现。
n 消息命名,在一个大型项目中,需要一套详细的规则。相信我,否则你会吃苦头的。特别是多人参与项目中,如果没有按照一定规则命名,命名冲突可是会让你调试一阵。但不管你如何定义命名规则,【记住】为了模块间解耦,Notification发布者应该不关心谁对这个消息感兴趣(谁来处理),感兴趣者自行注册(Mediator通过listNotificationInterests注册、Command通过facade.registerCommand()注册)。例如当Proxy中用户信息改变时,不应该sendNotification通过“UpdateUserInfoVIew”、“UpdateFriendListView”2个通过来分别更新用户信息、好友列表中对应用户的信息,而只是发送一个通知,如“UpdateUserInfo”,用户信息栏、好友列表都注册这个消息,然后分别处理。
n 无法知道Notification的源头。然而这点可以通过在消息体body中,增加字段标识,如:
sendNotification(ApplicationConstants.UPDATE_LEVEL_DATA, { "noticeSource": this, "levelData": m_levelData } ); |
noticeSource标识消息来源,如果您还想要知道消息传递层次,可以用数组表示,顺序插入传递者。
1.2. 强松耦合加重通信次数
PureMVC中模块间通信推荐使用Notification机制,但是全部使用Notification这种强松耦合模式:①强松耦合加重通信次数;②带反馈数据的通信加重通信负担。
图:UI使用Notification修改Proxy中的数据通信过程
PureMVC中UI修改Proxy的数据并返回后刷新过程:Mediator收到UI提交事件后,发送Notification消息给Command;Command进行业务逻辑处理,调用Proxy接口修改数据(这里还可能涉及到与服务器通信),然后发消息给Mediator刷新,Mediator收到消息调用UI接口刷新。
因为都是消息机制,整个流程很长,而且Proxy中对数据进行操作后,发送Notification时,可能需要携带修改后的数据(可能是来自服务器的数据)。这个过程不仅通过次数多,而且带反馈数据的消息增加通信负担。另一方面要调试这个过程,我们只能在编译的时候找出一步一步的通信流程,才能跟踪调试。
2. 吐槽二:解耦增加了代码量,不方便调试
解耦的同时将使项目修改的复杂程度提高,某些解耦的办法还会增加代码量、降低执行效率。PureMVC是一个强解耦的框架,其效率本身不是很高,函数调用层次较深,而有时根本不清楚消息发到了哪里。
PureMVC为了实现解耦增加了代码量,不方便调试,但哪个MVC框架不是呢!这不是PureMVC的问题,已经有前辈编写了PureMVC模版,如FlashDevelop的模板(下载),使用模板可以减少手动编写代码量,但不能减少类的数量。
有篇文章详细介绍了PureMVC的耦合与解耦:耦合与脱耦——深入分析为什么使用pureMVC、接口或抽象基类(入口http://bbs.9ria.com/thread-161667-1-1.html)
3. 吐槽三:过度使用单例模式
单例模式过于万能,属于高耦合写法。PureMVC中有4个单例Model、View、Controller、Façade。我们可以通过Model、View、Controller的getInstance()方法获取实例,并对他们进行操作。然而Façade是用于管理Model、View、Controller并对外提供接口。如果Model、View、Controller对外不可见,为什么要设定为单例,而不是Façade的成员变量呢?
4. 总结
上面说了一些PureMVC的缺点,不过总体来说PureMVC还算一个优秀的框架,解耦彻底、灵活性高。
本文转自吴秦博客园博客,原文链接:http://www.cnblogs.com/skynet/archive/2013/02/17/2914742.html,如需转载请自行联系原作者