目前,较主流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 框架的一个中文版本,这是一款广泛应用的开源框架,特别设计用于构建富互联网应用程序(RIA),尤其是基于Adobe Flex和ActionScript 3的项目。PureMVC 提供了一种模块化、结构...
标题中的“可以运行的PureMVC的登陆实例”是指一个基于PureMVC框架的登录功能实现,这个实例已经经过验证可以在FlexBuilder3环境下正常运行。PureMVC是一种经典的多层应用架构模式,它为ActionScript、JavaScript、...
这个是一个根据AS3(ActionScript 3) pureMVC而转换过来的lua pureMVC。所有的接口完全跟AS3版本一致。 若是想使用,可以直接查看网上的pureMVC 文档,我并未对任何一个函数改名或者更换参数位置。 注意,这个PureMVC...
6. **Hello World示例**:通常会通过一个简单的“Hello World”程序来演示PureMVC的基本工作流程,展示如何创建并运行一个完整的MVC循环。 7. **源码分析**:可能对PureMVC的源码进行解析,帮助理解其内部机制和...
标题中的"PureMVC_CSharp.zip_csharp_pureMVC_pureMVC C_pureMVC C#"表明这是一个关于C#语言实现的PureMVC框架的压缩包。"疯铮铮"可能是作者或分享者的名字,也可能是对项目热情的表达。 描述中提到的"PureMVC_...
1. **MacroCommand**:宏命令是PureMVC的一个扩展,它允许将多个命令组合在一起,作为一个单一的命令执行,使得处理复杂流程变得更加简单。 2. **SimpleCommand**:简单命令是处理单个任务的命令,它接收通知,执行...
PureMVC是面向对象的多层应用程序框架,它提供了一种模式来组织代码,使开发更加规范和高效。本篇文章将深入探讨Unity中如何使用PureMVC框架,以及它如何帮助实现UI和逻辑的分离。 PureMVC是一个轻量级的框架,其...
PureMVC是一个开源的、轻量级的MVC(Model-View-Controller)框架,它最初是为ActionScript设计的,但后来发展出了多种语言版本,包括C#。本压缩包"PureMVC.rar"提供了PureMVC在C#平台上的实现,包括单线程版和多...
**PureMVC框架详解** PureMVC是一种轻量级、模型-视图-控制器(MVC)框架,最初是为ActionScript开发的,后来被移植到多种编程语言中,包括C++。它提供了一种组织代码结构的方式,使得开发者可以更高效地构建可维护...
通过这个实例,开发者可以了解PureMVC的完整工作流程,从而在自己的项目中更好地应用这个强大的框架。学习这个实例,不仅能加深对MVC模式的理解,还能提升在ActionScript或Flex环境下的开发能力。
《深入理解PureMVC:基于五子棋游戏的源码分析》 PureMVC是一个流行的、开源的、轻量级的、跨平台的MVC框架,它为开发人员提供了一种结构化的编程模式,用于组织和管理应用程序的业务逻辑、用户界面和数据。在这个...
PureMvc是一个开源的、轻量级的框架,用于构建多层结构的富客户端应用程序。它遵循Model-View-Controller(MVC)设计模式,并提供了一种标准化的方式来组织和协调应用程序的各个部分。在这个名为"MyFirstPureMvc"的...
三、PureMVC工作流程 1. 用户交互:用户在View层进行操作,触发事件。 2. Mediator响应:Mediator监听到事件后,创建并发送一个Notification。 3. Controller处理:Controller接收到Notification,根据类型调用相应...
Qt版本的PureMVC是一个基于设计模式的框架,主要用于构建可维护性和可扩展性极高的应用程序。这个框架的实现是将经典的MVC(Model-View-Controller)模式应用于Qt编程环境,为Qt开发者提供了一种结构化的方法来组织...
纯MVC(PureMVC)是一个轻量级的框架,用于构建基于模型-视图-控制器(Model-View-Controller)设计模式的应用程序。这个框架最初是为ActionScript编程语言设计的,但后来被移植到了多种其他编程语言中,包括Java、...
7. **问题与解决方案**:列出常见问题和解决策略,帮助开发者避免和解决在使用PureMVC过程中遇到的问题。 通过这个教程,开发者可以系统地学习并掌握PureMVC,从而提升在项目开发中的架构设计和代码组织能力。同时...
如你下载后的存放的目录是D组:/下载,解压后将创建一个名为PureMVC_AS3_2_0_4的文件夹(注:其中的2_0_4是版本号) ; 打开PureMVC_AS3_2_0_4文件夹,您会发现里面有三个文件夹: asdoc :对应于API的文档,它的首页...
PureMVC是一个多范式、轻量级的框架,它主要设计用于构建应用程序的模型-视图-控制器(MVC)结构。这个框架的核心理念是将应用程序的不同部分解耦,以便于开发、维护和扩展。在C++版本的PureMVC中,它充分利用了面向...
该框架的设计灵感来源于经典的MVC设计模式,旨在简化开发过程,提高代码的可维护性和可扩展性。 标题中提到的"PureMVC各种例子"是指PureMVC框架提供的一系列示例项目,这些例子可以帮助开发者快速理解如何在实际...
纯MVC(PureMVC)是一个轻量级的框架,主要设计用于构建应用程序的模型-视图-控制器架构。这个框架最初是为ActionScript 3编程语言开发的,但现在已经被移植到许多其他编程语言,包括Java、C#、Python、JavaScript等...