目前,较主流Flex框架大致可分为两大类,一类是正规军MVC--Cairngorm&pureMVC,一类是自由军MVC兼IOC--swiz、mate、parsley、spring as。
正规军的MVC是在既定模式下运作整个流程,而这个模式的形成是以解耦为原则的职责划分,优点自然是权责清晰,而其不足在于过于正规化使得工作量或效率被转嫁,一个看似小小的需求,也要动辄整个流程,使得小需求付出过多(即程序员编码量过大)。
在这里,简单认识一下正规军中的pureMVC,认识她的一般处理流程、她的优缺点以及她可能的折中。
pureMVC一般处理流程如下图:
特点:①MEDIATOR耦合VIEW在于解耦VIEW与其它部分的耦合性,通过MEDIATOR直接对VIEW数据收集与更新负责;
②MEDIATOR、COMMAND以及PROXY直接通过通知解耦,并合理完成后台调用后反馈数据更新;
代价:①强松耦合加重通信次数;②带反馈数据的通信加重通信负担;
折中:采用面向接口编程/依赖注入,变强松耦合为松耦合,同时可减少通信次数;
接下来,用代码陈列的方式来感性认识pureMVC的一般处理流程(样例主线:model-view-mediator-command-proxy-other command):
Example
用户与View Component和Mediator的交互
假如有一个含表单的LoginPanel组件。对应有一个LoginPanelMediator,负责与LoginPanel交互并响应它的输入信息发送登录请求。
LoginPanel和LoginPanelMediator之间的协作表现为:LoginPanel在用户输入完信息要登录时发送一个TRY_LOGIN的事件,LoginPanelMediator处理这个事件,处理方法是发送一个以组件包含的LoginVO为“报体”的Notification(通知)。
LoginVO.as
package com.me.myapp.model.vo
{
//把这个AS3 VO映射到Remote Class
[RemoteClass(alias="com.me.myapp.model.vo.LoginVO")]
[Bindable]
public class LoginVO
{
public var username: String;
public var password: String;
public var authToken: String;//登录权限允许时服务器设置此值
}
}
LoginPanel.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml"
title="Login" status=”{loginStatus}”>
<!—
The events this component dispatches. Unfortunately we can’t use
the constant name here, because MetaData is a compiler directive
-->
<mx:MetaData>
[Event('tryLogin')];
</mx:MetaData>
<mx:Script>
<![CDATA[
import com.me.myapp.model.vo.LoginVO;
// 表单项与LoginVO对象的属性双向绑定。
[Bindable] public var loginVO:LoginVO = new LoginVO();
[Bindable] public var loginStatus:String = NOT_LOGGED_IN;
//义定Event名称常量
public static const TRY_LOGIN:String='tryLogin';
public static const LOGGED_IN:String='Logged In';
public static const NOT_LOGGED_IN:String='Enter Credentials';
]]>
</mx:Script>
<mx:Binding source="username.text" destination="loginVO.username"/>
<mx:Binding source="password.text" destination="loginVO.password"/>
<!—The Login Form -->
<mx:Form id="loginForm" >
<mx:FormItem label="Username:">
<mx:TextInput id="username" text="{loginVO.username}" />
</mx:FormItem>
<mx:FormItem label="Password:">
<mx:TextInput id="password" text="{loginVO.password}"
displayAsPassword="true" />
</mx:FormItem>
<mx:FormItem >
<mx:Button label="Login" enabled="{loginStatus == NOT_LOGGED_IN}”
click="dispatchEvent( new Event(TRY_LOGIN, true ));"/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
LoginPanel组件包含有一个用用户表单输入新创建的LoginVO对象,当用户单击“Login”按钮时触发一个事件,接下来的事情由LoginPanelMediator接管。
这样View Component的角色就是简单收集数据,收集完数据通知系统。
可以完善的地方是只有当username和password都有内容时才让login按钮可用(enable),这样可以避免恶意登录。
View Component对外隐藏自己的内部实现,它由Mediator使用的整个API包括:一个TRY_LOGIN事件,一个LoginVO属性和Panel的状态属性。
LoginPanelMediator会对LOGIN_FAILED和LOGIN_SUCCESS通知做出反应,设置LoginPanel的状态。
LoginPanelMediator.as:
package com.me.myapp.view
{
import flash.events.Event;
import org.puremvc.as3.interfaces.*;
import org.puremvc.as3.patterns.mediator.Mediator;
import com.me.myapp.model.LoginProxy;
import com.me.myapp.model.vo.LoginVO;
import com.me.myapp.ApplicationFacade;
import com.me.myapp.view.components.LoginPanel;
// LoginPanel视图的Mediator
public class LoginPanelMediator extends Mediator implements IMediator
{
public static const NAME:String = 'LoginPanelMediator';
public function LoginPanelMediator( viewComponent:LoginPanel ) {
super( NAME, viewComponent );
LoginPanel.addEventListener( LoginPanel.TRY_LOGIN, onTryLogin );
}
// 列出该Mediator关心的Notification
override public function listNotificationInterests( ) : Array {
return [
LoginProxy.LOGIN_FAILED,
LoginProxy.LOGIN_SUCCESS
];
}
// 处理Notification
override public function handleNotification( note:INotification ):void {
switch ( note.getName() ) {
case LoginProxy.LOGIN_FAILED:
LoginPanel.loginVO = new LoginVO( );
loginPanel.loginStatus = LoginPanel.NOT_LOGGED_IN;
break;
case LoginProxy.LOGIN_SUCCESS:
loginPanel.loginStatus = LoginPanel.LOGGED_IN;
break;
}
}
// 户单击用Login钮尝试录按,登。
private function onTryLogin ( event:Event ) : void {
sendNotification( ApplicationFacade.LOGIN, loginPanel.loginVO );
}
// 把viewComponent转类化成它真正的型。
protected function get loginPanel() : LoginPanel {
return viewComponent as LoginPanel;
}
}
}
注意LoginPanelMediator在构造方法中给LoginPanel注册了一个侦听方法——onTryLogin,当用户单击Login按钮时这个方法会被执行。在onTryLogin方法里发送了一个LOGIN的Notification(通知,携带参数LoginVO对象)。
早先(在ApplicationFacade中)我们已经把LoginCommand注册到这个Notification上了。LoginCommand会调用LoginProxy的“登录”方法,传参LoginVO。LoginProxy把“登录”请求远程服务,之后发送LOGIN_SUCCESS(登录成功)或LOGIN_FAILED(登录失败)的Notification。这些类的定义请参见“Proxy”章节。
LoginPanelMediator把LOGIN_SUCCESS和LOGIN_FAILED注册自己的关心的Notification,当这两个Notification被发送时,Mediaotr作为响应把LoginPanel的loginStatus设置为LOGGED_IN(登录成功时)或NOT_LOGGED_IN(登录失败时),并清除LoginVO对象。
LoginCommand.as
package com.me.myapp.controller {
import org.puremvc.as3.interfaces.*;
import org.puremvc.as3.patterns.command.*;
import com.me.myapp.model.LoginProxy;
import com.me.myapp.model.vo.LoginVO;
public class LoginCommand extends SimpleCommand {
override public function execute( note: INotification ) : void {
var loginVO : LoginVO = note.getBody() as LoginVO;
var loginProxy: LoginProxy;
loginProxy = facade.retrieveProxy( LoginProxy.NAME ) as LoginProxy;
loginProxy.login( loginVO );
}
}
}
LoginProxy.as
package com.me.myapp.model
{
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
import org.puremvc.as3.interfaces.*;
import org.puremvc.as3.patterns.proxy.Proxy;
import com.me.myapp.model.vo.LoginVO;
// 用于用户登录的Proxy
public class LoginProxy extends Proxy implements IProxy {
public static const NAME:String = 'LoginProxy';
public static const LOGIN_SUCCESS:String = 'loginSuccess';
public static const LOGIN_FAILED:String = 'loginFailed';
public static const LOGGED_OUT:String = 'loggedOut';
private var loginService: RemoteObject;
public function LoginProxy () {
super( NAME, new LoginVO ( ) );
loginService = new RemoteObject();
loginService.source = "LoginService";
loginService.destination = "GenericDestination";
loginService.addEventListener( FaultEvent.FAULT, onFault );
loginService.login.addEventListener( ResultEvent.RESULT, onResult );
}
// 隐式getter,转化data的类型
public function get loginVO( ) : LoginVO {
return data as LoginVO;
}
//如果logivVO中包含了authToken(授权标识)表示用户登录成功
public function get loggedIn():Boolean {
return ( authToken != null );
}
// 取得authToken
public function get authToken():String {
return loginVO.authToken;
}
//置用的限设户权标识,登录,退出,或登继续尝试录。
public login( tryLogin:LoginVO ) : void {
if ( ! loggedIn ) {
loginVO.username= tryLogin.username;
loginVO.password = tryLogin.password;
} else {
logout();
login( tryLogin );
}
}
// 退出,地清空简单LoginVO
public function logout( ) : void
{
if ( loggedIn ) loginVO = new LoginVO( );
sendNotification( LOGGED_OUT );
}
//通知系登成功统录
private function onResult( event:ResultEvent ) : void
{
setData( event.result ); // immediately available as loginVO
sendNotification( LOGIN_SUCCESS, authToken );
}
//通知系登失统录败
private function onFault( event:FaultEvent) : void
{
sendNotification( LOGIN_FAILED, event.fault.faultString );
}
}
}
一个LoginCommand会获取LoginProxy,设置登录的数据,调用登录函数,呼叫登录服务。
接下来,可能一个GetPrefsCommand会响应LOGIN_SUCCESS(登录成功)这个Notification,从Notificaiton的“报体”中获取authToken(授权标识),接着呼叫下一个服务,获取用户的(比如)配置信息(preferences)。
GetPrefsCommand.as
package com.me.myapp.controller {
import org.puremvc.as3.interfaces.*;
import org.puremvc.as3.patterns.command.*;
import com.me.myapp.model.LoginProxy;
import com.me.myapp.model.vo.LoginVO;
public class GetPrefsCommand extends SimpleCommand {
override public function execute( note: INotification ) : void {
var authToken : String = note.getBody() as String;
var prefsProxy : PrefsProxy;
prefsProxy = facade.retrieveProxy( PrefsProxy.NAME ) as PrefsProxy;
prefsProxy.getPrefs( authToken );
}
}
}
由于此次给出的感性认识在于pureMVC的处理流程,因此,关于整个流程流转的配置略,若您有兴趣或者期望更进一步了解pureMVC,了解Mediator、Command、Proxy各自的职责等,可参见附件的那份中文文档或访问官网。
分享到:
相关推荐
PureMVC教程,是学习PureMVC框架的好文章,PureMVC教程,是学习PureMVC框架的好文章,PureMVC教程,是学习PureMVC框架的好文章PureMVC教程,是学习PureMVC框架的好文章,PureMVC教程,是学习PureMVC框架的好文章,PureMVC...
如你下载后的存放的目录是D组:/下载,解压后将创建一个名为PureMVC_AS3_2_0_4的文件夹(注:其中的2_0_4是版本号) ; 打开PureMVC_AS3_2_0_4文件夹,您会发现里面有三个文件夹: asdoc :对应于API的文档,它的首页...
PureMVC五子棋游戏源码,学习PureMVC
用PureMvc开发Air项目,完整工程实例。 学PureMvc的第一个完整例子
这是一个使用C#开发语言的基于PureMVC框架的Web登录Demo,是网上绝无仅有的实例。 本文以初学者的视角,详细地介绍PureMVC在ASP.NET的应用。 PureMVC不仅仅是Flex的MVC框架哦,而且它非常的小巧,还等什么呢,快来...
按照puremvc官方网站教程做的登陆实例,在flexBuilder3上运行过.绝对好用. 供大家学习参考.
这是一个MVC例子,简单的接受了MVC的实现过程。
这个是一个根据AS3(ActionScript 3) pureMVC而转换过来的lua pureMVC。所有的接口完全跟AS3版本一致。 若是想使用,可以直接查看网上的pureMVC 文档,我并未对任何一个函数改名或者更换参数位置。 注意,这个PureMVC...
PureMVC学习资料与案例PureMVC学习资料与案例PureMVC学习资料与案例PureMVC学习资料与案例
pureMVC项目包 导入的包 pureMVC项目包pureMVC项目包
pureMVC框架 pureMVC源码 学习pureMVC的知识
介绍了PureMVC框架结构以及PureMVC下消息发送机制,有助于更好的了解和学习PureMVC架构
flex PureMVC框架实例 flex PureMVC框架
适合Unity的pureMVC,做UI和逻辑分成。比较适合的工具
pureMVC框架dll文件,
Flex framework ,又一个新的flex界面框架
puremvc 讲解puremvc的源码
本例子运用PureMVC框架编写的简单例子,初学者可以通过本例子理解PureMVC的实现过程,各层的主要职责及如何通信.
一个以pureMVC为flex前端框架,blazeds为通信服务器,spring和hibernate为服务端框架,实现了增删改等功能的完整实例,数据库使用mysql,部分关键地方加了注释,enjoy!
puremvc .net 2.0 /vs2010 使用PUREMVC