puremvc框架之hello world!

puremvc是一个可应用于多种语言、多种平台的mvc框架。根据官网上的描述,现在已经支持下列语言:

官方也推出了最佳实践的中文文档,当然,园子里也有兄弟说它烂的 :)

 

跟asp.net mvc框架有所不同,在asp.net mvc中,一个http请求过来,controller会自动去取得数据,最终转化为model,然后选取一个view进行呈现,同时把model传到view中,一切还算比较简单。

 

然而puremvc除mvc模式外,渗杂了更多的模式:比如facade(门面),observer(观察者),singleton(单件)等等

先不管其它,来一个flex版本的Hello World吧。(注:以下内容参考了Pure MVC第一步:最简PureMVC)

整个项目结构:

这个项目最终就是要在界面上显示一个文本框,一个按钮,点击按钮时,文本框内容发生改变。(注:该项目纯粹是为了puremvc而puremvc,不具实践意义,仅仅只是出于学习目的,刻意简化的一个示例) 另:因为这个项目不涉及具体的数据实体类,所以model这部分就省去了。

在puremvc中,model/view/controller统一是由Facade类的单件实例来统筹管理的。

大致流程可理解为:通过Facade类的单件实例(即:统一的门面) 启动 puremvc环境,启动同时注册Command对象(相当于asp.net mvc中的controller),然后Command通过与之关联的facade(即前面的单件实例)来注册Mediator(中介者:用于把View与Command联系起来)。

当UI界面(即View)上有动静时(比如按钮点击了之类),与之关联的Mediator(中介者)会发送通知给facade,然后facade会调用command对象执行相关的处理。(即:消息响应)

 

应该不难理解吧:

1、先在flash builder中创建一个flex项目,同时添加puremvc相关的swc引用,然后主界面main.mxml内容如下:

1
2
3
4
5
6
7
8
9
10
11
<?xml version= "1.0"  encoding= "utf-8" ?>
<s:Application xmlns:fx= "http://ns.adobe.com/mxml/2009"
                xmlns:s= "library://ns.adobe.com/flex/spark"
                xmlns:mx= "library://ns.adobe.com/flex/mx"  minWidth= "300"  minHeight= "200"  height= "42"  width= "300"  >
     <fx:Declarations>
         <!-- Place non-visual elements (e.g., services, value objects) here -->
     </fx:Declarations>
 
     <s:TextInput x= "10"  y= "10"  width= "206"  id= "txtResult" />
     <s:Button x= "224"  y= "9"  label = "Button"  id= "btnSend" />
</s:Application>

2、创建门面AppFacade类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package  mvc
{
     import  mvc.controller.AppCommand;
     
     import  org.puremvc.as3.interfaces.IFacade;
     import  org.puremvc.as3.patterns.facade.Facade;
 
     public  class  AppFacade extends  Facade implements  IFacade
     {
         public  static  const  START_UP: String = "start_up" ;
         public  static  const  CHANGE_TEXT: String = "change_text" ;
 
         public  function  AppFacade()
         {
 
         }
 
         public  static  function  getInstance():AppFacade
         {
             if  (instance == null )
             {
                 instance= new  AppFacade();
             }
             return  instance as  AppFacade;
         }
 
         protected  override  function  initializeController(): void
         {
             super .initializeController();
             this .registerCommand(START_UP, AppCommand); //入口:注册Command
         }
 
         //启动puremvc环境
         public  function  startup(_main:main): void
         {
             //注:这里的main即为UI界面main.mxml对应的类
             this .sendNotification(START_UP, _main); //启动时,发送通知
         }
     }
}

当然,这不是一个严格意义的单件(构造函数仍然可调用,不过这里不想把代码弄得太复杂,大家暂时把它当做一个单件来看待吧) 。

注:注意这里加注释的部分,在initializeController中,注册了一个Command对象(AppCommand在代码下面会贴出),这样就把门面Facade与命令Command联系起来了,另外在startup里,把主界面main.mxml对应的类实例使用_main传递进来,这样puremvc环境就跟程序主类联系起来了。

3、创建AppCommand类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package  mvc.controller
{
     import  mvc.view.ButtonMediator;
     import  mvc.view.TextMediator;
 
     import  org.puremvc.as3.interfaces.INotification;
     import  org.puremvc.as3.patterns.command.SimpleCommand;
 
     public  class  AppCommand extends  SimpleCommand
     {
         public  function  AppCommand()
         {
             super ();
         }
 
         public  override  function  execute(inote:INotification): void
         {
             var  _main:main=inote.getBody() as  main;
             //注册:中介者(用于连接view与command)
             facade.registerMediator( new  TextMediator(_main.txtResult));
             facade.registerMediator( new  ButtonMediator(_main.btnSend));
         }
     }
}

注:这里的execute方法中,通过facade引用,得到puremvc中的门面Facade唯一实例,然后注册Mediator中介者,把界面上的元素(即输入框与按钮)跟门面也关联起来了。

4、中介者(TextMediator与ButtonMediator)

这也是跟asp.net mvc不同的一个地方,puremvc并没有直接操作视图(View)上的元素,而是引入了中介者(Mediator)这个概念,它相当于“View上的具体元素”与Command之间的桥梁,这样的好处,就是进一步解耦,从一定程度上消除对具体界面的依赖。

ButtonMediator.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package  mvc.view
{
     import  spark.components.Button;
     import  flash.events.MouseEvent;
     import  mvc.AppFacade;
     
     import  org.puremvc.as3.interfaces.IMediator;
     import  org.puremvc.as3.patterns.mediator.Mediator;
     
     public  class  ButtonMediator extends  Mediator implements  IMediator
     {
         public  static  const  NAME: String  = "ButtonMediator" ;
         
         public  function  ButtonMediator(viewComponent:Button)
         {
             super (NAME,viewComponent);
             this .btnInstance.addEventListener(MouseEvent.CLICK,btnClick);
             
         }
         
         private  function  btnClick(e:MouseEvent): void {
             this .sendNotification(AppFacade.CHANGE_TEXT, "Hello PureMVC !" );
         }
         
         //获取UI界面上的“按钮实例"
         private  function  get  btnInstance():Button{
             return  viewComponent as  Button;
         }
     }
}

可以看到,ButtonMediator通过调用sendNotification方法向puremvc环境发送消息CHANGE_TEXT就完事了,至于谁去接收消息,它不关心。

 

TextMediator.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package  mvc.view
{
     import  spark.components.TextInput;
     import  mvc.AppFacade;
     
     import  org.puremvc.as3.interfaces.IMediator;
     import  org.puremvc.as3.interfaces.INotification;
     import  org.puremvc.as3.patterns.mediator.Mediator;
 
     public  class  TextMediator extends  Mediator implements  IMediator
     {
         public  static  const  NAME: String  = "TextMediator" ;
         
         public  function  TextMediator(viewComponent:TextInput)
         {
             super (NAME,viewComponent);
         }
         
         public  override  function  listNotificationInterests(): Array {
             return  [AppFacade.CHANGE_TEXT];
         }
         
         //响应消息
         public  override  function  handleNotification(notification:INotification): void
         {
             switch (notification.getName()){
                 case  AppFacade.CHANGE_TEXT:
                     this .txtInstance.text = notification.getBody() as  String ;
                     break ;
             }
         }
         
         //获取与之关联的UI界面上的“文本输入框”
         private  function  get  txtInstance():TextInput{
             return  viewComponent as  TextInput;
         }
     }
}

在这段代码中,TextMediator负责监听CHANGE_TEXT消息,同时得到消息后,会做出反应。这样跟上面的ButtonMediaor一唱一合,完成了整个消息的处理。

 

ok,代码准备得差不多了,回过头在main.mxml中正式启用puremvc环境吧: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version= "1.0"  encoding= "utf-8" ?>
<s:Application xmlns:fx= "http://ns.adobe.com/mxml/2009"
                xmlns:s= "library://ns.adobe.com/flex/spark"
                xmlns:mx= "library://ns.adobe.com/flex/mx"  minWidth= "300"  minHeight= "200"  height= "42"  width= "300"  creationComplete= "application1_creationCompleteHandler(event)" >
     <fx:Declarations>
         <!-- Place non-visual elements (e.g., services, value objects) here -->
     </fx:Declarations>
     
     <fx:Script>      
         <![CDATA[
             import  mvc.AppFacade;              
             import  mx.events.FlexEvent;    
         
             protected  function  application1_creationCompleteHandler(event:FlexEvent): void
             {
                 //启动puremvc环境
                 AppFacade.getInstance().startup( this );         
             }
         ]]>
     </fx:Script>
     <s:TextInput x= "10"  y= "10"  width= "206"  id= "txtResult" />
     <s:Button x= "224"  y= "9"  label = "Button"  id= "btnSend" />
</s:Application>

示例源代码下载 (flash builder4环境)

 

最后再附上一张puremvc的结构图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值