`

pureMVC一般流程通览小记

阅读更多

    目前,较主流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各自的职责等,可参见附件的那份中文文档或访问官网

0
0
分享到:
评论

相关推荐

    PureMVC 中文版

    标题 "PureMVC 中文版" 指的是 PureMVC 框架的一个中文版本,这是一款广泛应用的开源框架,特别设计用于构建富互联网应用程序(RIA),尤其是基于Adobe Flex和ActionScript 3的项目。PureMVC 提供了一种模块化、结构...

    可以运行的puremvc的登陆实例.

    标题中的“可以运行的PureMVC的登陆实例”是指一个基于PureMVC框架的登录功能实现,这个实例已经经过验证可以在FlexBuilder3环境下正常运行。PureMVC是一种经典的多层应用架构模式,它为ActionScript、JavaScript、...

    Lua实现PureMVC

    这个是一个根据AS3(ActionScript 3) pureMVC而转换过来的lua pureMVC。所有的接口完全跟AS3版本一致。 若是想使用,可以直接查看网上的pureMVC 文档,我并未对任何一个函数改名或者更换参数位置。 注意,这个PureMVC...

    PureMVC总结(附Hello World含PureMVC源码代码和文档)

    6. **Hello World示例**:通常会通过一个简单的“Hello World”程序来演示PureMVC的基本工作流程,展示如何创建并运行一个完整的MVC循环。 7. **源码分析**:可能对PureMVC的源码进行解析,帮助理解其内部机制和...

    PureMVC_CSharp.zip_csharp_pureMVC_pureMVC C_pureMVC C#_疯铮铮

    标题中的"PureMVC_CSharp.zip_csharp_pureMVC_pureMVC C_pureMVC C#"表明这是一个关于C#语言实现的PureMVC框架的压缩包。"疯铮铮"可能是作者或分享者的名字,也可能是对项目热情的表达。 描述中提到的"PureMVC_...

    pureMVC_AS3

    1. **MacroCommand**:宏命令是PureMVC的一个扩展,它允许将多个命令组合在一起,作为一个单一的命令执行,使得处理复杂流程变得更加简单。 2. **SimpleCommand**:简单命令是处理单个任务的命令,它接收通知,执行...

    Unity 专用 pureMVC

    PureMVC是面向对象的多层应用程序框架,它提供了一种模式来组织代码,使开发更加规范和高效。本篇文章将深入探讨Unity中如何使用PureMVC框架,以及它如何帮助实现UI和逻辑的分离。 PureMVC是一个轻量级的框架,其...

    PureMVC.rar

    PureMVC是一个开源的、轻量级的MVC(Model-View-Controller)框架,它最初是为ActionScript设计的,但后来发展出了多种语言版本,包括C#。本压缩包"PureMVC.rar"提供了PureMVC在C#平台上的实现,包括单线程版和多...

    基于PureMVC框架实现的Qt的一个例子

    **PureMVC框架详解** PureMVC是一种轻量级、模型-视图-控制器(MVC)框架,最初是为ActionScript开发的,后来被移植到多种编程语言中,包括C++。它提供了一种组织代码结构的方式,使得开发者可以更高效地构建可维护...

    一个很好的puremvc实例

    通过这个实例,开发者可以了解PureMVC的完整工作流程,从而在自己的项目中更好地应用这个强大的框架。学习这个实例,不仅能加深对MVC模式的理解,还能提升在ActionScript或Flex环境下的开发能力。

    PureMVC五子棋游戏源码,学习PureMVC

    《深入理解PureMVC:基于五子棋游戏的源码分析》 PureMVC是一个流行的、开源的、轻量级的、跨平台的MVC框架,它为开发人员提供了一种结构化的编程模式,用于组织和管理应用程序的业务逻辑、用户界面和数据。在这个...

    PureMvc实例 PureMvc第一个实例

    PureMvc是一个开源的、轻量级的框架,用于构建多层结构的富客户端应用程序。它遵循Model-View-Controller(MVC)设计模式,并提供了一种标准化的方式来组织和协调应用程序的各个部分。在这个名为"MyFirstPureMvc"的...

    PureMVC_study

    三、PureMVC工作流程 1. 用户交互:用户在View层进行操作,触发事件。 2. Mediator响应:Mediator监听到事件后,创建并发送一个Notification。 3. Controller处理:Controller接收到Notification,根据类型调用相应...

    qt版本pureMVC

    Qt版本的PureMVC是一个基于设计模式的框架,主要用于构建可维护性和可扩展性极高的应用程序。这个框架的实现是将经典的MVC(Model-View-Controller)模式应用于Qt编程环境,为Qt开发者提供了一种结构化的方法来组织...

    pureMVC源代码

    纯MVC(PureMVC)是一个轻量级的框架,用于构建基于模型-视图-控制器(Model-View-Controller)设计模式的应用程序。这个框架最初是为ActionScript编程语言设计的,但后来被移植到了多种其他编程语言中,包括Java、...

    PureMVC中文教程

    7. **问题与解决方案**:列出常见问题和解决策略,帮助开发者避免和解决在使用PureMVC过程中遇到的问题。 通过这个教程,开发者可以系统地学习并掌握PureMVC,从而提升在项目开发中的架构设计和代码组织能力。同时...

    pureMVC安装包,SDK

    如你下载后的存放的目录是D组:/下载,解压后将创建一个名为PureMVC_AS3_2_0_4的文件夹(注:其中的2_0_4是版本号) ; 打开PureMVC_AS3_2_0_4文件夹,您会发现里面有三个文件夹: asdoc :对应于API的文档,它的首页...

    PureMVC C++架构代码

    PureMVC是一个多范式、轻量级的框架,它主要设计用于构建应用程序的模型-视图-控制器(MVC)结构。这个框架的核心理念是将应用程序的不同部分解耦,以便于开发、维护和扩展。在C++版本的PureMVC中,它充分利用了面向...

    PureMVC 各种例子以及中文文档

    该框架的设计灵感来源于经典的MVC设计模式,旨在简化开发过程,提高代码的可维护性和可扩展性。 标题中提到的"PureMVC各种例子"是指PureMVC框架提供的一系列示例项目,这些例子可以帮助开发者快速理解如何在实际...

    pureMVC资料包

    纯MVC(PureMVC)是一个轻量级的框架,主要设计用于构建应用程序的模型-视图-控制器架构。这个框架最初是为ActionScript 3编程语言开发的,但现在已经被移植到许多其他编程语言,包括Java、C#、Python、JavaScript等...

Global site tag (gtag.js) - Google Analytics