pureMVC简单示例及其原理讲解

pureMVC是一个MVC框架,皆在最大限度的减少MVC间的耦合性。本人刚刚接触pureMVC时感到一头雾水,不知从何入手,也不知道从何学习。好在本人有耐性且能看懂英文技术文档,面向对象的编程能力也比较扎实。在这种背景下,终于悟出了pureMVC的原理,能够使用pureMVC进行开发。如果把pureMVC的领悟境界分为若干,我是处于最低境界(潜力很大啊)。好,闲话不说,言归正传。

本示例是在理解了官方示例EmployeeAdmin示例的基础之上的简化版,用意是为了更好的理解pureMVC。

界面:图片上部控件用于添加用户,下部控件用户显示用户信息和删除已添加的用户

图片

【图1】

 

首先:

pureMVC既然是MVC(Model、View、Controller)框架,那你就必须要记住pureMVC中的四个主要结构类:

  • Proxy(相当于Model)
  • Mediator(相当于View)
  • Command(相当于Controller)
  • Facade(管理Proxy、Mediator和Command的东西)

也许上面小括号中的话说的不严谨,在本示例中MVC是这样划分的:

  1. Model:由VO(Value Object,即值对象)和Proxy组成;
  2. Mediator:由图1中的两个MXML文件及其对应的Mediator组成;
  3. Command:由一个MacroCommand和若干个SimpleCommand组成;
  4. Facade:即ApplicationFacade;
  5. 启动页:MyPureMVCDemo.mxml文件。

整个示例由以上五个部分组成。具体如图2所示。







图片

【图2】

 

这里关于3和4要做一下解释。pureMVC中的Command分为两种:多命令和单一命令,即MacroCommand和 SimpleCommand。MacroCommand中通过addSubCommand(SimpleCommandName)来加入子命令,两个 Command中的方法都需要被重写override,此外还需要通过facade.registerCommand(...)注册命令。也许这段话我说的不清楚,你只要记住pureMVC框架包含这五个部分就可以了,咱们往下看吧!

 

pureMVC是一个MVC框架,皆在最大限度保持Model、View、Controller的独立性,从而减少各个层间的耦合。

上一篇《pureMVC简单示例及其原理讲解——开篇 》中讲述了本示例宗旨、主要功能文件结构,此外还介绍了pureMVC包含的核心组成。

回顾:

本节将讲述Model层。

Model层有VO和Mediator组成,非常简单,仅仅包含两个类:UserVO和UserProxy。

UserVO中的构造器用于初始化用户的添加(通过email和密码),另一个isValid属性验证用户电子邮件是否合法以及密码长度。

Uservo.as代码
  1. /**  
  2. UserVO  
  3. 作者:吴磊  
  4. */  
  5. package com.superwulei.model.vo {  
  6.   
  7.     public class UserVO {  
  8.   
  9.         public var email:String = '';            //电子邮件  
  10.         public var password:String = '';         //密码  
  11.         public var regDate:Date;                 //注册日期  
  12.   
  13.         public function UserVO(email:String, password:String) {  
  14.             this.email = email;  
  15.             this.password = password;  
  16.             this.regDate = new Date();  
  17.         }  
  18.   
  19.         /*  
  20.         验证用户信息  
  21.         email:以单词字符开始,以.cn结尾  
  22.         password:     长度大于等于6位  
  23.         */  
  24.         public function get isValid():Boolean {  
  25.             var emailRegExp:RegExp = /^\w+[@]\w+(.com)$/;  
  26.             return (emailRegExp.test(this.email) && this.password.length >= 6);  
  27.         }  
  28.     }  
  29. }  
/**
UserVO
作者:吴磊
*/
package com.superwulei.model.vo {

public class UserVO {

public var email:String = '';            //电子邮件
public var password:String = '';         //密码
public var regDate:Date;                 //注册日期

public function UserVO(email:String, password:String) {
this.email = email;
this.password = password;
this.regDate = new Date();
}

/*
验证用户信息
email:以单词字符开始,以.cn结尾
password:     长度大于等于6位
*/
public function get isValid():Boolean {
var emailRegExp:RegExp = /^\w+[@]\w+(.com)$/;
return (emailRegExp.test(this.email) && this.password.length >= 6);
}
}
}

 

UserProxy代码如下。UserProxy继承Proxy。在Proxy中有一个类型为Object的data私有变量,这样就可以使用这个 Object的变量存储任何数据。在UserProxy构造方法中,我们通过super方法调用父类构造器并将Object的data转换为 ArraryCollect类型。由于data是私有了,因此我们通过getter返回属性的公有方法返回"ArrayCollection"类型的 data。同时定义两个其他的方法用于向这个users属性中添加、删除对象。其实大家现在应该可以看出来了,这个users属性存在的目的其实就是为了存储UserVO对象。

Userproxy.as代码
  1. package com.superwulei.model  
  2. {  
  3.     import com.superwulei.model.vo.UserVO;  
  4.       
  5.     import mx.collections.ArrayCollection;  
  6.       
  7.     import org.puremvc.as3.patterns.proxy.Proxy;  
  8.   
  9.     public class UserProxy extends Proxy  
  10.     {  
  11.         public static const NAME:String = 'UserProxy';  
  12.           
  13.         public function UserProxy()  
  14.         {  
  15.             super(NAME,new ArrayCollection());  
  16.         }  
  17.           
  18.         public function get users():ArrayCollection{  
  19.             return data as ArrayCollection;  
  20.         }  
  21.         /* 添加项 */  
  22.         public function addItem(item:Object):void{  
  23.             users.addItem(item);  
  24.         }  
  25.         /* 删除项 */  
  26.         public function deleteItem(item:Object):void{  
  27.             var user:UserVO = item as UserVO;  
  28.             for(var i:int = 0; i < users.length; i++){  
  29.                 if(users[i].email == user.email){  
  30.                     users.removeItemAt(i);  
  31.                 }  
  32.             }  
  33.         }  
  34.     }  
  35. }  
package com.superwulei.model
{
import com.superwulei.model.vo.UserVO;

import mx.collections.ArrayCollection;

import org.puremvc.as3.patterns.proxy.Proxy;

public class UserProxy extends Proxy
{
public static const NAME:String = 'UserProxy';

public function UserProxy()
{
super(NAME,new ArrayCollection());
}

public function get users():ArrayCollection{
return data as ArrayCollection;
}
/* 添加项 */
public function addItem(item:Object):void{
users.addItem(item);
}
/* 删除项 */
public function deleteItem(item:Object):void{
var user:UserVO = item as UserVO;
for(var i:int = 0; i < users.length; i++){
if(users[i].email == user.email){
users.removeItemAt(i);
}
}
}
}
}

Model层非常简单,pureMVC设计的追求同样如此,Model层应该是稳定的、不会由于其他层的变化而变化。

本节中讲解了Model层,关键的一点是Proxy中的data,非常重要,很有意义。

 

pureMVC是一个MVC框架,目的是为了将Model、View、Controller严格的划分出来。pureMVC可以用户Java、C#、ActionScript等多种编程语言。

上一篇《pureMVC简单示例及其原理讲解——Model层 》中我们讲解了Model层,非常简单。包含一个UserVO和一个UserProxy,只要记住Proxy中的data的含义就OK了。

本篇说的是View层,即视图层,在本示例中包括两个部分:MXML文件,即可视控件;Mediator。

可视控件

可视控件由UserForm.mxml(图1)和UserList.mxml(图2)两个文件组成。UserForm.mxml用于添加用户,UserList.mxml显示用户和删除已添加用户。

 

【图1】

图片图片

【图2】

 

先看UserForm.mxml,既然要添加用户,就一定会要一个方法。你还记得么,在上一篇《pureMVC简单示例及其原理讲解——Model层 》中我们提到的UserProxy中有一个ArrayCollection类型的users属性和无返回值的addItem方法,其中users中存储 UserVO,addItem方法用来向users中添加UserVO。现在我们既然要在界面通过添加按钮添加用户,我们必然要用到这个方法,但是我们不会在View层直接使用这个方法。因为pureMVC的追求是将MVC分离,而这些逻辑操作我们都会将其放入Command中,即Controller才层。但是在View层,我们也不是没有作为的。我先调一调你的胃口,不要着急,这个作为我们会在本篇接下来的部分讲。先看看userForm.mxml的代码。

Userform.mxml代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Panel title="Registor" xmlns:mx="http://www.adobe.com/2006/mxml">  
  3.     <mx:Metadata>  
  4.         [Event('add')]  
  5.     </mx:Metadata>  
  6.   
  7.     <mx:Script>  
  8.         <![CDATA[  
  9.             import mx.controls.Alert;  
  10.             import com.superwulei.model.vo.UserVO;  
  11.             public static const USER_ADD:String = "add";  
  12.   
  13.             public var user:UserVO;  
  14.             /* 添加用户 */  
  15.             private function addUser():void {  
  16.                 user = new UserVO(email.text, password.text);  
  17.                 dispatchEvent(new Event(USER_ADD));  
  18.             }  
  19.   
  20.             private function enableSubmit(u:String, p:String):Boolean {  
  21.                 return u != '' && p != '';  
  22.             }  
  23.         ]]>  
  24.     </mx:Script>  
  25.   
  26.     <mx:Form>  
  27.         <mx:FormItem label="email" required="true">  
  28.             <mx:TextInput id="email"/>  
  29.         </mx:FormItem>  
  30.         <mx:FormItem label="password" required="true">  
  31.             <mx:TextInput id="password" displayAsPassword="true"/>  
  32.         </mx:FormItem>  
  33.     </mx:Form>  
  34.       
  35.     <mx:ControlBar horizontalAlign="right">  
  36.         <mx:Button id="sbumitButton" label="添加"  
  37.              enabled="{enableSubmit(email.text,password.text)}"  
  38.              click="addUser();"/>  
  39.     </mx:ControlBar>  
  40. </mx:Panel>  
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel title="Registor" xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Metadata>
[Event('add')]
</mx:Metadata>

<mx:Script>
<![CDATA[
import mx.controls.Alert;
import com.superwulei.model.vo.UserVO;
public static const USER_ADD:String = "add";

public var user:UserVO;
/* 添加用户 */
private function addUser():void {
user = new UserVO(email.text, password.text);
dispatchEvent(new Event(USER_ADD));
}

private function enableSubmit(u:String, p:String):Boolean {
return u != '' && p != '';
}
]]>
</mx:Script>

<mx:Form>
<mx:FormItem label="email" required="true">
<mx:TextInput id="email"/>
</mx:FormItem>
<mx:FormItem label="password" required="true">
<mx:TextInput id="password" displayAsPassword="true"/>
</mx:FormItem>
</mx:Form>

<mx:ControlBar horizontalAlign="right">
<mx:Button id="sbumitButton" label="添加"
 enabled="{enableSubmit(email.text,password.text)}"
 click="addUser();"/>
</mx:ControlBar>
</mx:Panel>

 在UserForm.mxml中定义一个Event,并对应的定义一个USER_ADD常量。来看看点击添加按钮后会怎么样?找到 submitButton按钮的click事件对应的方法addUser。在addUser方法中,首先要生成一个UserVO对象user,这个 user存储的信息就是你在界面上输入的email和密码;此外还要注意,这个UserVO的对象user事先已经声明,且是public的访问修饰符。之所以将user的访问限制设定为公有的,是由于这个user会在其他地方用到,这个其他地方请您关注。

一般的,一个可视控件会对应一个Mediator;但有时候多个可视控件也会对应一个Mediator。本示例中,可视控件和Mediator的关系是前者,即一对一。来看看UserForm.mxml对应的UserFormMediator.as代码。

Userformmediator.as代码
  1. package com.superwulei.view  
  2. {  
  3.     import com.superwulei.ApplicationFacade;  
  4.     import com.superwulei.view.components.UserForm;  
  5.       
  6.     import flash.events.Event;  
  7.       
  8.     import org.puremvc.as3.patterns.mediator.Mediator;  
  9.   
  10.     public class UserFormMediator extends Mediator  
  11.     {  
  12.         public static const NAME:String = "UserFormMediator";  
  13.                   
  14.         public function UserFormMediator(viewComponent:Object)  
  15.         {  
  16.             super(NAME, viewComponent);  
  17.             userForm.addEventListener(UserForm.USER_ADD,onAdd);  
  18.         }  
  19.           
  20.         private function get userForm():UserForm{  
  21.             return viewComponent as UserForm;  
  22.         }  
  23.           
  24.         /* 添加用户监听器 */  
  25.         private function onAdd(event:Event):void{  
  26.             add();  
  27.         }  
  28.         /* 添加用户方法 */  
  29.         private function add():void{  
  30.             sendNotification(ApplicationFacade.USER_ADDED,userForm.user);  
  31.         }  
  32.     }  
  33. }  
package com.superwulei.view
{
import com.superwulei.ApplicationFacade;
import com.superwulei.view.components.UserForm;

import flash.events.Event;

import org.puremvc.as3.patterns.mediator.Mediator;

public class UserFormMediator extends Mediator
{
public static const NAME:String = "UserFormMediator";

public function UserFormMediator(viewComponent:Object)
{
super(NAME, viewComponent);
userForm.addEventListener(UserForm.USER_ADD,onAdd);
}

private function get userForm():UserForm{
return viewComponent as UserForm;
}

/* 添加用户监听器 */
private function onAdd(event:Event):void{
add();
}
/* 添加用户方法 */
private function add():void{
sendNotification(ApplicationFacade.USER_ADDED,userForm.user);
}
}
}

 在View层,Mediator是pureMVC的核心,其私有变量viewComponent表示一个可视控件,上例中viewComponent表示UserForm,通过userForm属性实现。

看构造器UserFromMediator(...)。首先调用了父类的构造方法;然后给userForm属性加上onAdd监听器,这个 userFrom属性是通过getter方法实现的,见get userForm():UserForm。来看onAdd监听器,调用add方法,在add方法中使用了sendNotification方法。刚才我们所说的添加用户的方法不是没有作为,这就是我所谓的有所作为,即“发送通知”。pureMVC中将逻辑控制放在了Controller层,因此在View 层就不会有添加用户的代码,但是我们将“添加用户”这个命令以通知的方式发送出去。注意sendNotification方法中携带了两个参数,第一个参数是一个常量,第二个参数是一个UserVO对象。这个常量表示会调用与之对应的Command,这个UserVO对象表示的就是要添加的用户。这个在 Controller层会讲到。

UserList.mxml和UserListMediator.as和上面的道理是类似的,在此不多言。以下是UserList.mxml和UserListMediator.as的代码。

Userlist.mxml代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" title="已注册用户">  
  3.     <mx:Metadata>  
  4.     [Event('delete')]  
  5. </mx:Metadata>  
  6.   
  7.     <mx:DataGrid id="userGrid" dataProvider="{users}">  
  8.         <mx:Script>  
  9.             <![CDATA[  
  10.                 import mx.formatters.DateFormatter;  
  11.                 import com.superwulei.model.vo.UserVO;  
  12.                 import mx.collections.ArrayCollection;  
  13.                   
  14.                 public static const USER_DELETE:String = "delete";  
  15.                   
  16.                 [Bindable]  
  17.                 public var users:ArrayCollection;  
  18.                   
  19.                 public var selectUser:UserVO;  
  20.   
  21.                 private function deleteUser():void{  
  22.                     selectUser = userGrid.selectedItem as UserVO;  
  23.                     dispatchEvent(new Event(USER_DELETE));  
  24.                 }  
  25.             ]]>  
  26.         </mx:Script>  
  27.         <mx:columns>  
  28.             <mx:DataGridColumn dataField="email"/>  
  29.             <mx:DataGridColumn dataField="password"/>  
  30.             <mx:DataGridColumn dataField="regDate" width="200"/>  
  31.         </mx:columns>  
  32.     </mx:DataGrid>  
  33.     <mx:HBox textAlign="center">  
  34.         <mx:Button id="deleteButton" label="删除" click="deleteUser();"/>  
  35.     </mx:HBox>  
  36. </mx:Panel>  
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" title="已注册用户">
<mx:Metadata>
[Event('delete')]
</mx:Metadata>

<mx:DataGrid id="userGrid" dataProvider="{users}">
<mx:Script>
<![CDATA[
import mx.formatters.DateFormatter;
import com.superwulei.model.vo.UserVO;
import mx.collections.ArrayCollection;

public static const USER_DELETE:String = "delete";

[Bindable]
public var users:ArrayCollection;

public var selectUser:UserVO;

private function deleteUser():void{
selectUser = userGrid.selectedItem as UserVO;
dispatchEvent(new Event(USER_DELETE));
}
]]>
</mx:Script>
<mx:columns>
<mx:DataGridColumn dataField="email"/>
<mx:DataGridColumn dataField="password"/>
<mx:DataGridColumn dataField="regDate" width="200"/>
</mx:columns>
</mx:DataGrid>
<mx:HBox textAlign="center">
<mx:Button id="deleteButton" label="删除" click="deleteUser();"/>
</mx:HBox>
</mx:Panel>

 

Userlistmediator.as代码
  1. package com.superwulei.view  
  2. {  
  3.     import com.superwulei.ApplicationFacade;  
  4.     import com.superwulei.model.UserProxy;  
  5.     import com.superwulei.view.components.UserList;  
  6.       
  7.     import flash.events.Event;  
  8.       
  9.     import org.puremvc.as3.patterns.mediator.Mediator;  
  10.   
  11.     public class UserListMediator extends Mediator  
  12.     {  
  13.         private var userProxy:UserProxy;  
  14.           
  15.         public static const NAME:String = "UserListMediator";  
  16.           
  17.         public function UserListMediator(viewComponent:Object)  
  18.         {  
  19.             super(NAME, viewComponent);  
  20.             userList.addEventListener(UserList.USER_DELETE,onDelete);  
  21.             userProxy = facade.retrieveProxy(UserProxy.NAME) as UserProxy;  
  22.             userList.users = userProxy.users;  
  23.         }  
  24.           
  25.         private function get userList():UserList{  
  26.             return viewComponent as UserList;  
  27.         }  
  28.         /* 删除用户监听器 */  
  29.         private function onDelete(event:Event):void{  
  30.             deleteUser();  
  31.         }  
  32.         /*删除用户方法*/  
  33.         private function deleteUser():void{  
  34.             sendNotification(ApplicationFacade.USER_DELETE,userList.selectUser);  
  35.         }  
  36.           
  37.     }  
  38. }  
package com.superwulei.view
{
import com.superwulei.ApplicationFacade;
import com.superwulei.model.UserProxy;
import com.superwulei.view.components.UserList;

import flash.events.Event;

import org.puremvc.as3.patterns.mediator.Mediator;

public class UserListMediator extends Mediator
{
private var userProxy:UserProxy;

public static const NAME:String = "UserListMediator";

public function UserListMediator(viewComponent:Object)
{
super(NAME, viewComponent);
userList.addEventListener(UserList.USER_DELETE,onDelete);
userProxy = facade.retrieveProxy(UserProxy.NAME) as UserProxy;
userList.users = userProxy.users;
}

private function get userList():UserList{
return viewComponent as UserList;
}
/* 删除用户监听器 */
private function onDelete(event:Event):void{
deleteUser();
}
/*删除用户方法*/
private function deleteUser():void{
sendNotification(ApplicationFacade.USER_DELETE,userList.selectUser);
}

}
}

 关于Mediator再补充一下,在每个Mediator中会看到有一个公有的静态的常量字符串,这个字符串用来表示Mediator的类名。同样的在Proxy和Command中你也会看到,这样就可以通过facade的retrieveMediator、retrieveProxy和 retieveCommand来检索对象。

 

关于Model层要记住:一个MXML可视控件对应一个Mediator,Mediator本身不处理操作但它会发送Notification(发送出去的Notification会自动被执行),关于界面上的操作采用监听的方式即addEventLisentner。

 

pureMVC由Proxy、Mediator、Command(SimpleCommand/MacroCommand)和Facade组成。

 

上一节讲述了示例的Model层,Model层由可视控件和Mediator组成,Mediator本身不控制各种操作,但是会将操作以通知的方式发送出去。本节将讲述pureMVC示例中的Controller层。

Controller层有以下文件组成:

  • AddUserCommand.as
  • DeleteUserCommand.as
  • ModelPrepCommand.as
  • ViewPrepCommand.as
  • StartupCommand.as

AddUserCommand 。顾名思义,它是添加用户命令。让我们首先看看代码。

Addusercommand.as代码
  1. package com.superwulei.controller  
  2. {  
  3.     import com.superwulei.model.UserProxy;  
  4.     import com.superwulei.model.vo.UserVO;  
  5.       
  6.     import mx.controls.Alert;  
  7.       
  8.     import org.puremvc.as3.interfaces.INotification;  
  9.     import org.puremvc.as3.patterns.command.SimpleCommand;  
  10.   
  11.     public class AddUserCommand extends SimpleCommand  
  12.     {  
  13.         override public function execute(notification:INotification):void  
  14.         {  
  15.               
  16.             var user:UserVO = notification.getBody() as UserVO;  
  17.             var userProxy:UserProxy = facade.retrieveProxy(UserProxy.NAME) as UserProxy;  
  18.               
  19.             if(user.isValid){  
  20.                 userProxy.addItem(user);  
  21.             }else{  
  22.                 Alert.show("请检查用户名和密码");  
  23.             }  
  24.         }  
  25.           
  26.     }  
  27. }  
package com.superwulei.controller
{
import com.superwulei.model.UserProxy;
import com.superwulei.model.vo.UserVO;

import mx.controls.Alert;

import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;

public class AddUserCommand extends SimpleCommand
{
override public function execute(notification:INotification):void
{

var user:UserVO = notification.getBody() as UserVO;
var userProxy:UserProxy = facade.retrieveProxy(UserProxy.NAME) as UserProxy;

if(user.isValid){
userProxy.addItem(user);
}else{
Alert.show("请检查用户名和密码");
}
}

}
}

 AddUserCommand是一个单一命令(SimpleCommand),自定义SimpleCommand必须继承SimpleCommand并重写execute方法。execute方法表示这个命令的执行。曾经在上一篇《pureMVC简单示例及其原理讲解——View层 》中提到的添加用户的逻辑代码,应该在这里编写。还记得上一篇中提到的“View层本身不处理各种操作,但是发送通知”么?

上一篇中发送通知的代码
sendNotification(ApplicationFacade.USER_ADD,userForm.user);

 拿出这段代码是特意的想说明AddUserCommand的execute方法中的notification.getBody()其实就是 userForm.user,严谨的说应该是userFrom.user作为参数传到execute方法中来。如此我们在这里通过 userProxy.addItem(user)就实现了用户的添加。userProxy中的users就多了一个user。

 

DeleteUserCommand ,删除用户命令。代码如下,与添加用户道理一样,不多言。

Deleteusercommand deleteusercommand.as代码
  1. package com.superwulei.controller  
  2. {  
  3.     import com.superwulei.model.UserProxy;  
  4.     import com.superwulei.model.vo.UserVO;  
  5.       
  6.     import org.puremvc.as3.interfaces.INotification;  
  7.     import org.puremvc.as3.patterns.command.SimpleCommand;  
  8.   
  9.     public class DeleteUserCommand extends SimpleCommand  
  10.     {  
  11.         override public function execute(notification:INotification):void  
  12.         {  
  13.             var user:UserVO = notification.getBody() as UserVO;  
  14.             var userProxy:UserProxy = facade.retrieveProxy(UserProxy.NAME) as UserProxy;  
  15.             userProxy.deleteItem(user);  
  16.         }  
  17.           
  18.     }  
  19. }  
package com.superwulei.controller
{
import com.superwulei.model.UserProxy;
import com.superwulei.model.vo.UserVO;

import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;

public class DeleteUserCommand extends SimpleCommand
{
override public function execute(notification:INotification):void
{
var user:UserVO = notification.getBody() as UserVO;
var userProxy:UserProxy = facade.retrieveProxy(UserProxy.NAME) as UserProxy;
userProxy.deleteItem(user);
}

}
}

 ModelPrepCommand、ViewPrepCommand分别是Model层注册和View层注册。说道注册就要道一道。在 pureMVC中,一切总控制是facade,因此无论是Proxy、Mediator还是Command都要在facade中注册。上面四个 Command全部为SimpleCommand,最后一个StartupCommand为MacroCommand(复合命令)。 StartupCommand包含了多个SimpleCommand,通过addSubCommand方法添加了子命令,并在之后在facade上注册了 AddUserCommand和DeleteUserCommand。

Modelprepcommand.as代码
  1. package com.superwulei.controller  
  2. {  
  3.     import com.superwulei.model.UserProxy;  
  4.       
  5.     import org.puremvc.as3.interfaces.INotification;  
  6.     import org.puremvc.as3.patterns.command.SimpleCommand;  
  7.   
  8.     public class ModelPrepCommand extends SimpleCommand  
  9.     {  
  10.         override public function execute(notification:INotification):void  
  11.         {  
  12.             /* 注册Model */  
  13.             facade.registerProxy(new UserProxy());  
  14.         }  
  15.     }  
  16. }  
package com.superwulei.controller
{
import com.superwulei.model.UserProxy;

import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;

public class ModelPrepCommand extends SimpleCommand
{
override public function execute(notification:INotification):void
{
/* 注册Model */
facade.registerProxy(new UserProxy());
}
}
}

 

Viewprepcommand.as代码
  1. package com.superwulei.controller  
  2. {  
  3.     import com.superwulei.view.UserFormMediator;  
  4.     import com.superwulei.view.UserListMediator;  
  5.       
  6.     import org.puremvc.as3.interfaces.INotification;  
  7.     import org.puremvc.as3.patterns.command.SimpleCommand;  
  8.   
  9.     public class ViewPrepCommand extends SimpleCommand  
  10.     {  
  11.         override public function execute(notification:INotification):void  
  12.         {  
  13.             var app:MyPureMVCdemo = notification.getBody() as MyPureMVCdemo;  
  14.             /* 注册View */  
  15.             facade.registerMediator(new UserFormMediator(app.userForm));  
  16.             facade.registerMediator(new UserListMediator(app.userList));  
  17.         }  
  18.     }  
  19. }  
package com.superwulei.controller
{
import com.superwulei.view.UserFormMediator;
import com.superwulei.view.UserListMediator;

import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;

public class ViewPrepCommand extends SimpleCommand
{
override public function execute(notification:INotification):void
{
var app:MyPureMVCdemo = notification.getBody() as MyPureMVCdemo;
/* 注册View */
facade.registerMediator(new UserFormMediator(app.userForm));
facade.registerMediator(new UserListMediator(app.userList));
}
}
}

 

Startupcommand.as代码
  1. package com.superwulei.controller  
  2. {  
  3.     import com.superwulei.ApplicationFacade;  
  4.       
  5.     import org.puremvc.as3.patterns.command.MacroCommand;  
  6.   
  7.     public class StartupCommand extends MacroCommand  
  8.     {  
  9.         override protected function initializeMacroCommand():void{  
  10.             addSubCommand(ModelPrepCommand);  
  11.             addSubCommand(ViewPrepCommand);  
  12.             /* 注册添加、删除用户命令 */  
  13.             facade.registerCommand(ApplicationFacade.USER_ADD,AddUserCommand);  
  14.             facade.registerCommand(ApplicationFacade.USER_DELETE,DeleteUserCommand);  
  15.         }  
  16.     }  
  17. }  
package com.superwulei.controller
{
import com.superwulei.ApplicationFacade;

import org.puremvc.as3.patterns.command.MacroCommand;

public class StartupCommand extends MacroCommand
{
override protected function initializeMacroCommand():void{
addSubCommand(ModelPrepCommand);
addSubCommand(ViewPrepCommand);
/* 注册添加、删除用户命令 */
facade.registerCommand(ApplicationFacade.USER_ADD,AddUserCommand);
facade.registerCommand(ApplicationFacade.USER_DELETE,DeleteUserCommand);
}
}
}

 通过使用facade的registerCommand就好象添加一个监听器一样,当有sendNotification发送出来的时候,就会有对应的Command的execute方法被执行。

Controller层包含的应该是整个应用程序的逻辑业务。

 

pureMVC是一个MVC框架,核心部分包括Proxy、Mediator、Command和Facade,Facade同意管理前三个核心部分。

 

上一篇我们讲解了本示例中的Controller层,Controller层中包含添加用户命令、删除用户命令、注册View层的命令、注册 Model层的命令和一个复合命令注册所有的这些和添加/删除用户命令。至此为止,我们讲解了pureMVC示例的MVC三层,但是整个应用程序目前仍然无法启动,正确运行。不要着急,看完本节,程序就可以运行了。

本节将讲述Facade,Proxy、Mediator、Command的统一管家。自定义Facade必须继承Facade,在本示例中自定义Facade名称为ApplicationFacade,这个名称也是pureMVC组织建议的名称。先看代码:

 

Applicationfacade代码
  1. package com.superwulei {  
  2.     import com.superwulei.controller.StartupCommand;  
  3.       
  4.     import org.puremvc.as3.patterns.facade.Facade;  
  5.   
  6.     public class ApplicationFacade extends Facade {  
  7.         public static const STARTUP:String      = "startup";  
  8.         public static const USER_ADD:String     = "user_added";  
  9.         public static const USER_DELETE:String  = "user_delete";  
  10.   
  11.         public static function getInstance():ApplicationFacade {  
  12.             if (instance == null)  
  13.                 instance = new ApplicationFacade();  
  14.             return instance as ApplicationFacade;  
  15.         }  
  16.   
  17.         public function startup(app:Object):void {  
  18.             sendNotification(STARTUP, app);  
  19.         }  
  20.   
  21.         override protected function initializeController():void {  
  22.             super.initializeController();  
  23.             registerCommand(STARTUP, StartupCommand);  
  24.         }  
  25.     }  
  26. }  
package com.superwulei {
import com.superwulei.controller.StartupCommand;

import org.puremvc.as3.patterns.facade.Facade;

public class ApplicationFacade extends Facade {
public static const STARTUP:String      = "startup";
public static const USER_ADD:String     = "user_added";
public static const USER_DELETE:String  = "user_delete";

public static function getInstance():ApplicationFacade {
if (instance == null)
instance = new ApplicationFacade();
return instance as ApplicationFacade;
}

public function startup(app:Object):void {
sendNotification(STARTUP, app);
}

override protected function initializeController():void {
super.initializeController();
registerCommand(STARTUP, StartupCommand);
}
}
}

ApplicationFacade中使用了单例模式,即整个应用程序中只会存在一个ApplicationFacade的对象。不清楚单例模式的朋友们可以通过静态方法getInstance中的代码思考一下,是不是这样。方法initializeController被重写,首先调用父类的 initializeController方法,然后注册StartupCommand命令。还记得在上一章《pureMVC简单示例及其原理讲解——Controller 》中提到的StartupCommand么?它是一个复合命令,在这里注册了这个命令,其他的包括所有的Proxy、Mediator和 AddUserCommand、DeleteUserCommand也会被同时注册。看一个startup方法,有一个Object类型的参数 app,app接受的将是程序运行的类,没有它程序可以被加载但无法执行任何操作(这个方法具体细节本人有待研究,也欢迎广大朋友告之)。

主程序启动文件MyPureMVCdemo.mxml 代码

Mypuremvcdemo.mxml代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:components="com.superwulei.view.components.*"  
  3.     creationComplete="facade.startup(this);">  
  4.     <mx:Script>  
  5.         <![CDATA[  
  6.             import com.superwulei.ApplicationFacade;  
  7.             private var facade:ApplicationFacade = ApplicationFacade.getInstance();  
  8.         ]]>  
  9.     </mx:Script>  
  10.       
  11.     <components:UserForm id="userForm" />  
  12.     <components:UserList id="userList" />  
  13. </mx:Application>  
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:components="com.superwulei.view.components.*"
creationComplete="facade.startup(this);">
<mx:Script>
<![CDATA[
import com.superwulei.ApplicationFacade;
private var facade:ApplicationFacade = ApplicationFacade.getInstance();
]]>
</mx:Script>

<components:UserForm id="userForm" />
<components:UserList id="userList" />
</mx:Application>

 干净多了吧?在应用程序的creationComplete事件中加入facade.startup(this)的调用,其中this就表示的是当前启动类。这样一切就会通过facade走了。为方便各位更好的理解本文,本人已经将本示例上传,请点击下方的超级链接下载。

 

这样结束似乎很不圆满,我想在听到一些反馈之后在做小结,这样可以画上一个比较美的句号。

本人对于pureMVC的研究仅限于此,恳请各位pureMVC的研究者和使用者批评、指导!

 

上一篇

你可能感兴趣的:(编程,mvc,框架,Flash,Adobe)