pureMvc.docx
《pureMvc.docx》由会员分享,可在线阅读,更多相关《pureMvc.docx(66页珍藏版)》请在冰豆网上搜索。
![pureMvc.docx](https://file1.bdocx.com/fileroot1/2022-12/31/11054f6d-dc26-4e1c-8969-1189f85d3946/11054f6d-dc26-4e1c-8969-1189f85d39461.gif)
pureMvc
实现
术语阐述
及
最佳实践
用PureMVC创建健壮、易扩展、易维护的客户端程序
附ActionScript3及MXML实例
作者:
CliffHall
翻译:
张泽远<@>
Tamt<>
最后更新:
5/19/2008
PureMVC结构
4
∙
∙
∙
∙
∙
∙
∙
∙
Model与Proxy
View与Mediator
Controller与Command
Façade与Core
Observer与Notification
Notification可以被用来触发Command的执行
Mediator发送、声明、接收Notification
Proxy发送,但不接收Notification
4
4
4
5
5
5
6
6
Façade
7
∙
∙
∙
具体Façade是什么样子的?
为程序创建Façade
初始化Façade
7
7
10
Notification
12
∙
∙
Event与Notification
定义Notification和Event常量
12
13
Command
14
∙
∙
∙
SimpleCommand和MacroCommand的使用
降低Command与Mediator,Proxy的耦合度
复杂的操作与业务逻辑
15
15
16
PureMVC是Futurescale公司创建并维护的开源自由的程序框架。
Futurescale,Inc.Copyright©2006-08,Somerights
reserved。
使用PureMVC必须遵守美国CreativeCommons3.0Attribution协议。
PureMVC、本文档以及任何从
Futurescale网站下载的文档、培训资料及示例代码,都不提供任何明示或者默示的担保,包括但是不限于是否符合特定的
目的、未侵害他人权利的担保。
Page2of44
5/20/200811:
17PM
Mediator
21
∙
∙
∙
∙
∙
∙
Mediator的职责
转化ViewComponent类型
监听并响应ViewComponent
在Mediator里处理Notification
Mediator和Proxy之间、Mediator和其他Mediator之间的耦合
用户与ViewComponent和Mediator的交互
21
25
27
22
23
28
Proxy
33
∙
∙
∙
∙
∙
Proxy的职责
转换数据对象
避免对Mediator的依赖
封装域逻辑
与RemoteProxy通信
34
34
36
37
38
启示
PureMVC是一个定位于设计高性能RIA客户端的基于模式
的框架。
现在它已经被移植到其他的平台上,包括服务器
端环境。
本篇文档论述针对于客户端。
PureMVC在不同平台语言下的阐述、实现,PureMVC所
使用的模式在“四人帮”的《设计模式:
可复用面向对象
软件的基础》一书中有很好的论述。
强烈推荐。
PureMVC是Futurescale公司创建并维护的开源自由的程序框架。
Futurescale,Inc.Copyright©2006-08,Somerights
reserved。
使用PureMVC必须遵守美国CreativeCommons3.0Attribution协议。
PureMVC、本文档以及任何从
Futurescale网站下载的文档、培训资料及示例代码,都不提供任何明示或者默示的担保,包括但是不限于是否符合特定的
目的、未侵害他人权利的担保。
Page3of44
5/20/200811:
17PM
PureMVC结构
PureMVC框架的目标很明确,即把程序分为低耦合的三层:
Model、View和
Controller。
降低模块间的耦合性,各模块如何结合在一起工作对于创建易扩展,易维护的应用
程序是非常重要的。
在PureMVC实现的经典MVC元设计模式中,这三部分由三个单例模式类管理,分
别是Model、View和Controller。
三者合称为核心层或核心角色。
PureMVC中还有另外一个单例模式类——Façade,Façade提供了与核心层通信
的唯一接口,以简化开发复杂度。
Model与Proxy
Model保存对Proxy对象的引用,Proxy负责操作数据模型,与远程服务通
信存取数据。
这样保证了Model层的可移植性。
View与Mediator
View保存对Mediator对象的引用。
由Mediator对象来操作具体的视图组
件(ViewComponent,例如Flex的DataGrid组件),包括:
添加事件监
听器,发送或接收Notification,直接改变视图组件的状态。
这样做实现了把视图和控制它的逻辑分离开来。
Controller与Command
Controller保存所有Command的映射。
Command类是无状态的,只在需
要时才被创建。
PureMVC是Futurescale公司创建并维护的开源自由的程序框架。
Futurescale,Inc.Copyright©2006-08,Somerights
reserved。
使用PureMVC必须遵守美国CreativeCommons3.0Attribution协议。
PureMVC、本文档以及任何从
Futurescale网站下载的文档、培训资料及示例代码,都不提供任何明示或者默示的担保,包括但是不限于是否符合特定的
目的、未侵害他人权利的担保。
Page4of44
5/20/200811:
17PM
PureMVC结构
Controller与Command
Command可以获取Proxy对象并与之交互,发送Notification,执行其他
的Command。
经常用于复杂的或系统范围的操作,如应用程序的“启动”和
“关闭”。
应用程序的业务逻辑应该在这里实现。
Façade与Core
Façade类应用单例模式,它负责初始化核心层(Model,View和
Controller),并能访问它们的Public方法。
这样,在实际的应用中,你只需继承Façade类创建一个具体的Façade类就
可以实现整个MVC模式,并不需要在代码中导入编写Model,View和
Controller类。
Proxy、Mediator和Command就可以通过创建的Façade类来相互访问通
信。
Observer与Notification
PureMVC的通信并不采用Flash的EventDispatcher/Event,因为
PureMVC可能运行在没有FlashEvent和EventDispatcher类的环境中,
它的通信是使用观察者模式以一种松耦合的方式来实现的。
你可以不用关心PureMVC的Observer/Notification机制是怎么实现的,它
已经在框架内部实现了。
你只需要使用一个非常简单的方法从Proxy,
Mediator,Command和Facade发送Notification,甚至不需要创建一个
Notification实例。
Notification可以被用来触发Command的执行
Facade保存了Command与Notification之间的映射。
当Notification(通知)被
PureMVC是Futurescale公司创建并维护的开源自由的程序框架。
Futurescale,Inc.Copyright©2006-08,Somerights
reserved。
使用PureMVC必须遵守美国CreativeCommons3.0Attribution协议。
PureMVC、本文档以及任何从
Futurescale网站下载的文档、培训资料及示例代码,都不提供任何明示或者默示的担保,包括但是不限于是否符合特定的
目的、未侵害他人权利的担保。
Page5of44
5/20/200811:
17PM
PureMVC结构
Notification可以被用来触发Command的执行
发出时,对应的Command(命令)就会自动地由Controller执行。
Command实
现复杂的交互,降低View和Model之间的耦合性。
Mediator发送、声明、接收Notification
当用View注册Mediator时,Mediator的listNotifications方法会被调用,
以数组形式返回该Mediator对象所关心的所有Notification。
之后,当系统其它角色发出同名的Notification(通知)时,关心这个通知的
Mediator都会调用handleNotification方法并将Notification以参数传递到
方法。
Proxy发送,但不接收Notification
在很多场合下Proxy需要发送Notification(通知),比如:
Proxy从远程服
务接收到数据时,发送Notification告诉系统;或当Proxy的数据被更新时,
发送Notification告诉系统。
如果让Proxy也侦听Notification(通知)会导致它和View(视图)层、
Controller(控制)层的耦合度太高。
View和Controller必须监听Proxy发送的Notification,因为它们的职责是
通过可视化的界面使用户能与Proxy持有的数据交互。
不过对View层和Controller层的改变不应该影响到Model层。
例如,一个后台管理程序和一个面向用户程序可能共用一个Model类。
如果只
是用例不同,那么View/Controller通过传递不同的参数就可以共用相同的
Model类。
PureMVC是Futurescale公司创建并维护的开源自由的程序框架。
Futurescale,Inc.Copyright©2006-08,Somerights
reserved。
使用PureMVC必须遵守美国CreativeCommons3.0Attribution协议。
PureMVC、本文档以及任何从
Futurescale网站下载的文档、培训资料及示例代码,都不提供任何明示或者默示的担保,包括但是不限于是否符合特定的
目的、未侵害他人权利的担保。
Page6of44
5/20/200811:
17PM
Façade
MVC元设计模式的核心元素在PureMVC中体现为Model类、View类和
Controller类。
为了简化程序开发,PureMVC应用了Façade模式。
Façade是Model、View和Controller三者的“经纪人”。
实际编写代码时你
并不用导入这三者的类文件,也不用直接使用它们。
Façade类已经在构造方法包
含了对核心MVC三者单例的构造。
一般地,实际的应用程序都有一个Façade子类,这个Façade类对象负责初始
化Controller(控制器),建立Command与Notification名之间的映射,并执
行一个Command注册所有的Model和View。
具体Façade是什么样子的?
Façade类应被当成抽象类,永远不被直接实例化。
针对具体的应用程序,你应
该具体编写Façade的子类,添加或重写Façade的方法来实现具体的应用。
按照惯例,这个类命名为“ApplicationFacade”(当然,命名随你喜欢),
如前所述,它主要负责访问和通知Command,Mediator和Proxy。
通常,不同的运行平台都会创建视图结构,尽管创建过程不一样。
(比如Flex
中MXML程序负责实例化所有子视图组件,Flash影片在Stage上构建可视
对象)。
视图结构构建完毕时,整个PureMVC机制也已经安置妥当。
创建的Facade子类也被用来简化“启动”的过程。
应用程序调用Facade子
类的startup方法,并传递自身的一个引用即完成启动,使得应用程序不需要
过多了解PureMVC。
为程序创建Façade
Façade类的内容很简单。
思考下面的例子:
PureMVC是Futurescale公司创建并维护的开源自由的程序框架。
Futurescale,Inc.Copyright©2006-08,Somerights
reserved。
使用PureMVC必须遵守美国CreativeCommons3.0Attribution协议。
PureMVC、本文档以及任何从
Futurescale网站下载的文档、培训资料及示例代码,都不提供任何明示或者默示的担保,包括但是不限于是否符合特定的
目的、未侵害他人权利的担保。
Page7of44
5/20/200811:
17PM
Façade
为程序创建Façade
ApplicationFacade.as:
packagecom.me.myapp
{
importorg.puremvc.as3.interfaces.*;
importorg.puremvc.as3..patterns.facade.*;
importcom.me.myapp.view.*;
importcom.me.myapp.model.*;
importcom.me.myapp.controller.*;
//MyApp程序的Façade类
publicclassApplicationFacadeextendsFaçadeimplementsIFacade
{
//定义Notification(通知)常量
publicstaticconstSTARTUP:
String
publicstaticconstLOGIN:
String
="startup";
="login";
//得到ApplicationFacade单例的工厂方法
publicstaticfunctiongetInstance():
ApplicationFacade
{
if(instance==null)instance=newApplicationFacade();
returninstanceasApplicationFacade;
}
//注册Command,建立Command与Notification之间的映射
overrideprotectedfunctioninitializeController():
void
{
super.initializeController();
registerCommand(STARTUP,StartupCommand);
PureMVC是Futurescale公司创建并维护的开源自由的程序框架。
Futurescale,Inc.Copyright©2006-08,Somerights
reserved。
使用PureMVC必须遵守美国CreativeCommons3.0Attribution协议。
PureMVC、本文档以及任何从
Futurescale网站下载的文档、培训资料及示例代码,都不提供任何明示或者默示的担保,包括但是不限于是否符合特定的
目的、未侵害他人权利的担保。
Page8of44
5/20/200811:
17PM
Façade
为程序创建Façade
registerCommand(LOGIN,LoginCommand);
registerCommand(LoginProxy.LOGIN_SUCCESS,
GetPrefsCommand);
}
//启动PureMVC,在应用程序中调用此方法,并传递应用程序本身的引用
publicfunctionstartup(app:
MyApp):
void
{
sendNotification(STARTUP,app);
}
}
}
上述代码需要注意以下几点:
oApplicationFacade继承自PureMVC的Façade类,Façade
类实现了IFacade接口。
o这个例子里ApplicationFacade没有重写构造方法。
如果重写
构造方法,应该在构造方法里先调用父类的构造方法。
o类方法getInstance用于返回ApplicationFacade的单例,并
将实例保存在父类的一个protect变量中。
在返回该实例之前必
须先把它转化为ApplicationFacade类型。
o定义了Notification名称常量。
Façade类是整个系统其他角色相互
访问通信的核心,所以在这里定义Notification(通知)名称常量
是最合适的。
PureMVC是Futurescale公司创建并维护的开源自由的程序框架。
Futurescale,Inc.Copyright©2006-08,Somerights
reserved。
使用PureMVC必须遵守美国CreativeCommons3.0Attribution协议。
PureMVC、本文档以及任何从
Futurescale网站下载的文档、培训资料及示例代码,都不提供任何明示或者默示的担保,包括但是不限于是否符合特定的
目的、未侵害他人权利的担保。
Page9of44
5/20/200811:
17PM
Façade
为程序创建Façade
o初始化Controller(控制器),并建立Command与Notification之
间的映射,当Notification(通知)发出时相关的Command(命
令)就会被执行。
o提供一个带有应用程序类型参数的startup方法,该参数能过
Notification传递到StartupCommand。
实现这些只需要继承父类很少的功能。
初始化Façade
PureMVC的Façade类在构造方法中初始化了Model、View和
Controller对象,并把对它们的引用保存在成员变量。
这样,Façade就可以访问Model、View和Controller了。
这样把对核心
层的操作都集中在Façade,避免开发者直接操作核心层。
那么,在具体的应用程序中,Façade是何时何地初始化的呢?
请查看下面的
Flex代码:
MyApp.mxml:
xmlversion="1.0"encoding="utf-8"?
>
Applicationxmlns:
mx="
creationComplete="façade.startup(this)”>
Script>
[CDATA[
//获取ApplicationFacade
importcom.me.myapp.ApplicationFacade;
privatevarfacade:
ApplicationFacade=ApplicationFacade.getInstance();
]]>
PureMVC是Futurescale公司创建并维护的开源自由的程序框架。
Futurescale,Inc.Copyright©2006-08,Somerights
reserved。
使用PureMVC必须遵守美国CreativeCommons3.0Attribution协议。
PureMVC、本文档以及任何从
Futurescale网站下载的文档、培训资料及示例代码,都不提供任何明示或者默示的担保,包括但是不限于是否符合特定的
目的、未侵害他人权利的担保。
Page10of44
5/20/200811:
17PM
Façade
初始化Façade
Script>
—视图层的其他代码-->
Application>
上面这个程序很简单:
程序运行时创建视图结构,得到ApplicationFaçade实例,调用它的startup方法。
注意:
在AIR中,我们会使用“applicationComplete”代替这里的“creationComplete”;
在Flash中,我们可以把对startup的调用放在第1帧或文档类里。
请注意例子中以下几点:
o我们使用了MXML标签,这种普遍的方式,创建程序的界面。
以Application>标签开始,包含组件或容器,不管是Flex内
嵌的组件还是自定义的。
o声明并初始化了一个私有变量,(用于)获取ApplicationFacade
单例。
o我们初始化这个变量时使用了getInstance类方法,在应用程序的
creationComplete事件触发时,Facade和相关的Model,View,
Controller都已经实例化完毕(尽管此时还没有创建任何Mediator
和Proxy)。
o我们在Application标签中指定了对creationComplete事件的处理
过程:
调用startup方法,并传参主程序的引用。