`
houwei
  • 浏览: 61809 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Flex 开发架构(三): MVC框架-Flex Cairngorm

    博客分类:
  • Flex
阅读更多

有没有听说过这个奇怪的词汇:“Cairngorm”?如果你的回答是No && 你是Flex程序员,哪你就看看自己是不是住在一个井底。J 

 

CairngormFlex的一个MVC框架结构,名字取自苏格兰的一个山脉。(kao,如果是我建立一个自己的框架结构,我就取名叫:“xxx”。)

 

有关这个框架,在网络上有很多图表用来讨论。下面是我所理解的框架图表:

 

使用Cairngorm的第一步是建立框架结构的骨架,包括了三个对象:

 

Model Locater

Service Locator

Front Controller

 

Model Locator:承载了组件之间的所有的传递的信息和数据,这是一个Bindable(可绑定的)对象。

 

Service Locator:定义了与数据源(HttpserviceWebserviceRemoteobject)之间通讯的界面。

 

Front Controller:建立播送事件(Dispatch event)和命令层(command)之间的对应关系(mapping)。  

 

看一下相关的代码:

 

BuddyAppModelLocator.as:

package com.ny.flex.cairngorm.model
{
      import com.ny.flex.cairngorm.vo.User;
      
      import mx.collections.ArrayCollection;
      
      [Bindable]
      public class BuddyAppModelLocator
      {
            public var buddyList:ArrayCollection=new ArrayCollection();
            public var loginUser:User=new User();
            public var viewStackSelectedIndex :int = 0;
            
            static private var __instance:BuddyAppModelLocator=null;
            
            static public function getInstance():BuddyAppModelLocator
            {
                  if(__instance == null)
                  {
                        __instance=new BuddyAppModelLocator();
                  }
                  return __instance;
            }
      }
}



Model Locator代码中,定义了三个public的变量,buddyList:用来存放由数据库获取的密友列表;loginUser:定义一个User类型对象;viewStackSelectedIndex:定义viewStack指向的视窗。

几乎所有的服务层返回的信息都需要在Model Locator中有一个相应的对象。



BuddyServiceLocator.mxml:

<?xml version=”1.0″ encoding=”utf-8″?>
<cairngorm:ServiceLocator xmlns:mx=”http://www.adobe.com/2006/mxml” xmlns:cairngorm=”http://www.adobe.com/2006/cairngorm“>
      <mx:RemoteObject id=”buddyRo“  destination=”flexmvcRO” >
            
      </mx:RemoteObject>
</cairngorm:ServiceLocator>


 

上述代码定义了程序将要调用的RemoteObject RemoteObject 所调用的Destination需要和remote_config.xml文件中的Destination相一致。在此,Destination的值为“flexmvcRO”。

 

 

BuddyListController.as:


 

package com.ny.flex.cairngorm.control
{
      import com.adobe.cairngorm.control.FrontController;
      import com.ny.flex.cairngorm.command.GetBuddyListCommand;
      import com.ny.flex.cairngorm.command.LoginCommand;
      import com.ny.flex.cairngorm.event.GetBuddyListEvent;
      import com.ny.flex.cairngorm.event.LoginEvent;
 
      public class BuddyListController extends FrontController
      {
            public function BuddyListController()
            {
                  super();
                  addCommand(LoginEvent.LOGIN_EVENT,LoginCommand);      
                  addCommand(GetBuddyListEvent.GET_BUDDY_LIST_EVENT,
GetBuddyListCommand);
            }
            
      }
}


很显然,上述的Controller代码是事件和命令的对应处理的地方。

 

如何能将这些乱七八糟的东西结合在一起?其Magic的地方是在主页(Main application)上,代码如下:

 

BuddList_Main_Cairngorm.mxml:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml“  xmlns:service=”com.ny.flex.cairngorm.service.*“  xmlns:controller=”com.ny.flex.cairngorm.control.*” xmlns:views=”com.ny.flex.cairngorm.views.*” layout=”absolute“  width=”100%” height=”100%“>
<mx:Script>
      <![CDATA[
            import com.ny.flex.cairngorm.model.BuddyAppModelLocator;
      [Bindable]
      public var myModel:BuddyAppModelLocator = BuddyAppModelLocator.getInstance();
      ]]>
</mx:Script>
 
      <service:BuddyServiceLocator id=”myservice“/>
      <controller:BuddyListController id=”myController“/>
 
    <mx:HBox  horizontalAlign=”center” verticalAlign=”top“  width=”100%” height=”100%” y=”0” x=”0“>
    <mx:ViewStack id=”viewStack“  resizeToContent=”true” selectedIndex=”{myModel.viewStackSelectedIndex}” >
        <views:LoginView  />
        <views:BuddyListView/>
    </mx:ViewStack>
    </mx:HBox>
</mx:Application>



现在用户可以建立视图组件,并从这些组件中播送事件:


LoginView.mxml:

      <![CDATA[
            import com.ny.flex.cairngorm.event.LoginEvent;
            import com.ny.flex.cairngorm.vo.User;
            import mx.validators.Validator;
            private function login():void{
                  if(Validator.validateAll(validators).length == 0){
                        var loginUser:User = new User();
                        loginUser.userName=username.text;
                        loginUser.password=password.text;
                        var loginEvent:LoginEvent = new LoginEvent();
                        loginEvent.loginUser = loginUser;
                        loginEvent.dispatch();
                  }   
            }
      ]]>
</mx:Script>
 
 <!–  Validators–>
 <mx:Array id=”validators“>
    <mx:StringValidator  id=”userNameValidator” source=”{username}“  property=”text“  required=”true“/>
    <mx:StringValidator  id=”passwordValidator” source=”{password}“  property=”text” required=”true” />
 </mx:Array>    
 
 
<mx:Form id=”loginForm” x=”0” y=”0“>
          <mx:FormItem label=”Username:” >
               <mx:TextInput id=”username” />
           </mx:FormItem>
           <mx:FormItem label=”Password:” >
               <mx:TextInput id=”password” displayAsPassword=”true” />
           </mx:FormItem>
           <mx:FormItem direction=”horizontal” verticalGap=”15” paddingTop=”5” width=”170“>
               <mx:Button id=”loginBtn” label=”Login” click=”login()”/>
           </mx:FormItem>
    </mx:Form>
      
</mx:Panel>

 


每一个动作都需要建立一个相应的事件:





LoginEvent.as:

package com.ny.flex.cairngorm.event
{
      import com.adobe.cairngorm.control.CairngormEvent;
      import com.ny.flex.cairngorm.vo.User;
      
      import flash.events.Event;
 
      public class LoginEvent extends CairngormEvent
      {
            public static var LOGIN_EVENT:String = “loginEvent”
            public  var  loginUser:User ;
            
            public function LoginEvent()
            {
                  super(LOGIN_EVENT);
            }
 
            override public function clone() : Event
            {
                  return new LoginEvent();
            }
      }
}

 


每一个事件都 要对应于一个命令:

LoginCommand.as:

package com.ny.flex.cairngorm.command
{
      import com.adobe.cairngorm.commands.ICommand;
      import com.adobe.cairngorm.control.CairngormEvent;
      import com.ny.flex.cairngorm.event.LoginEvent;
      import com.ny.flex.cairngorm.model.BuddyAppModelLocator;
      import com.ny.flex.cairngorm.service.LoginDelegate;
      import com.ny.flex.cairngorm.vo.User;
      
      import mx.controls.Alert;
      import mx.rpc.IResponder;
 
      public class LoginCommand implements ICommand, IResponder
      {
            public function LoginCommand()
            {
            }
 
            public function execute(event:CairngormEvent):void
            {
                  var loginEvent:LoginEvent = LoginEvent(event);
                  var user:User = loginEvent.loginUser;
                  var lgoinService :LoginDelegate 
=  new LoginDelegate(this);
                  lgoinService.authenticate(user);
            }
            
            public function result(event:Object):void
            {
                  var authUser:User = User(event.result);
                  BuddyAppModelLocator.getInstance().loginUser = authUser;
                  BuddyAppModelLocator.getInstance().viewStackSelectedIndex=1;
            }
            
            public function fault(info:Object):void
            {
                  Alert.show(“Login Fail Error “);
            }
            
      }
}







然后,在Front Controller(前端控制器)中build对应关系:

 

 addCommand(LoginEvent.LOGIN_EVENT,LoginCommand);

 

命令层需要完成商务逻辑,用户需要在执行方法中加入商务逻辑代码:

 

                  var lgoinService :LoginDelegate =  
                                            new LoginDelegate(this);
                  lgoinService.authenticate(user);


Delegate(代表)用来通过服务层(Service Locator)调用数据源:

 

LoginDelegate.as:

package com.ny.flex.cairngorm.service
{
      import com.adobe.cairngorm.business.ServiceLocator;
      import com.ny.flex.cairngorm.vo.User;
      
      import mx.rpc.IResponder;
      
      public class LoginDelegate
      {
            private var responder:IResponder;
            private var service:Object;
            
            public function LoginDelegate(responder :IResponder){
              this.service = 
                           ServiceLocator.getInstance()
                                        .getRemoteObject(“buddyRo”);
              this.responder = responder;
            }
            
            public function  authenticate(user:User):void{
                  var call:Object = service.authenticate(user);
                  call.addResponder(responder);
            }
      }
}
 

 



返回的结果将回复到命令层(LoginCommand.as)的结果方法中,在此方法中Model被更新,然后数据被绑定到结果视图上:

LoginCommand.as:

            public function result(event:Object):void
            {
                  var authUser:User = User(event.result);
                  BuddyAppModelLocator.getInstance().loginUser
                                                                                    = authUser;
                        BuddyAppModelLocator.getInstance().viewStackSelectedIndex=1;
            }




其它的视图工作流程同上,整个密友列表项目的结构如下图所示:

 

使用Cairngorm开发应用项目Layer,测试性高。并且使得程序员更专业化。 

但这个框架的确很不容易学习和维护,那么有没有更好的方法简化它? 

 

来看看:咔嚓Front ControllerCairngorm









12
6
分享到:
评论
7 楼 wuxi15932077655 2009-04-07  
拜托不要使用这个字体好不好???  太累了
6 楼 zhengshina5 2009-02-18  
简单说下我对这个的理解

Cairngorm里的 ModelLocator目的应该是为了解决视图层之间的解耦,但是他真的能解决么?

我不认为,本身视图的状态就有很多种,并没有解决,本身Flex的项目就是一个swf,有人和我说ModelLocator是一个缓存,我不知道怎么去解释,你不用单例也是同样的

pureMvc使用观察者模式为了解决视图之间的切换,对视图的解耦的程度会高于Cairngorm,

CairngormEvent完全没有必要,只不过这个框架写上,感觉为了增加Cairngorm的知名度,根据不如自己去定义,自己去扩展会好,为什么呢?

因为你广播时要是Cairngorm的子类,如果是Event的子类就不行,不觉得很郁闷么?

他的Command我认为写的还是不错的,有一个叫Suq***Command的这个是解决多个Command要处理的内容的吧

ValueObject是个啥,基本没有用。呵呵

基本的看法吧,不过这个结构是很清晰的
5 楼 wuqiangjun_ql 2008-12-09  
学习一下,就是层次感觉不是很强!
4 楼 houwei 2008-08-28  
cairngorm的命名空间  是对的, 不知道你需要知道啥?
3 楼 kenees 2008-08-19  
麻烦解释一下下面这部分
<?xml version=”1.0″ encoding=”utf-8″?>
<cairngorm:ServiceLocator xmlns:mx=”http://www.adobe.com/2006/mxml” xmlns:cairngorm=”http://www.adobe.com/2006/cairngorm“>
      <mx:RemoteObject id=”buddyRo“  destination=”flexmvcRO” >
           
      </mx:RemoteObject>
</cairngorm:ServiceLocator>


这个cairngorm的命名空间对么?
2 楼 tj19832 2008-08-05  
现在的内存这么便宜,还买不起内存的人那里,能获取的商业价值也不多。

这个架构确实有点复杂
1 楼 xiaoY 2008-07-29  
沙发 ?
今天刚写的啊。呵呵。 我们组里现在也在研究这个。
你说的学习代价高。 我不知道到底有多高。
倒是简化这个词听的很合我意。
FLEX提倡富客户端, 这个框架在客户端做的MVC自成体系, 很符合这种思想。
不过有些小的模块,功能不复杂的, 一个mxml文件写完比劳师动众用个框架还要方便些。加上框架不知道会不会对性能做成影响
理论上不会,因为编译到swf的时候,link后也不会大多少。
不过总感觉前台,特别是Flex,要尽量简化一下,
现在FLEX的性能已经让很多没钱买内存的人痛苦了

相关推荐

    flex开发系列书籍:Cairngorm_MVC_框架

    Cairngorm 框架是 Adobe Flex 开发中的一个著名模型-视图-控制器(MVC)架构,它提供了一种结构化的方法来组织和管理应用程序代码,从而提高开发效率和代码可维护性。该框架的核心思想是将应用程序的不同部分——...

    Flex轻量级开发框架-Cairngorm介绍

    Cairngorm是Adobe官方推荐的一个轻量级Flex开发框架,主要基于MVC(Model-View-Controller)设计模式,旨在简化Flex应用程序的开发过程。相比于其他框架如PureMVC,Cairngorm更加简单易用,特别适合于小型到中型的...

    flex-Cairngorm框架

    Flex Cairngorm框架是Adobe Flex应用程序开发中的一个流行的设计模式,它基于Model-View-Controller(MVC)架构,旨在提高代码的可维护性和可扩展性。Cairngorm框架由SitePen公司开发,最初是为了满足大型企业级Flex...

    跟我StepByStep学FLEX教程------王一松

    - **Cairngorm框架**:Cairngorm是一个用于构建大型Flex应用的MVC框架。 - **设计理念**:介绍Cairngorm的设计理念及其在Flex开发中的作用。 #### 33. Cairngorm之组成部分 - **ModelLocator**:ModelLocator是...

    Flex开发框架cairngorm入门实例教程

    Cairngorm是一个轻量级的MVC框架,专门用于Adobe Flex应用程序的开发。这个框架的设计目的是为了提高Flex项目的可维护性和可扩展性,通过分离业务逻辑、视图和控制层,使得代码更加模块化。在Cairngorm中,模型...

    Flex流行MVC框架之Cairngorm

    Cairngorm是Adobe Flex开发中的一个著名的Model-View-Controller (MVC)框架,它为构建可维护、可扩展的富互联网应用程序(RIA)提供了结构化的开发模式。MVC模式是软件工程中的一种设计模式,它将应用程序分为三个主要...

    Flex-cairngorm-demo我喜欢的

    Flex Cairngorm 框架是一个..."Flex-cairngorm-demo我喜欢的"这个示例项目提供了实际操作的机会,通过它,开发者可以深入探索Cairngorm的用法,学习如何在实践中应用MVC模式,从而提升自身在Flex开发领域的专业技能。

    Flex流行MVC框架之Cairngorm小试牛刀

    Cairngorm就是一种在Flex中广泛采用的轻量级MVC框架。 Cairngorm由Adobe的首席架构师Rob Tarran创建,它为Flex应用提供了简单但强大的结构,使得开发者能够更好地管理应用程序的状态和业务逻辑。这个框架的核心组件...

    Spring Actionscript IOC 框架与 Flex Cairngorm MVC 应用开发

    在开发 Flex 应用程序时,Spring Actionscript IOC 框架和 Cairngorm MVC 模式结合使用,可以显著提升代码的可维护性和可扩展性。Spring Actionscript 是一个针对 Actionscript3 设计的轻量级框架,其灵感来源于 ...

    Art01-No.1 基于Cairngorm MVC框架的Flex程序设计与开发

    **基于Cairngorm MVC框架的Flex程序设计与开发** 在软件开发中,Model-View-Controller(MVC)架构模式被广泛应用于构建可维护、可扩展的应用程序。Cairngorm是Adobe Flex社区中一个知名的轻量级MVC框架,它为Flex...

    Flex MVC框架下载

    2. **Cairngorm**:Cairngorm是Adobe公司早期推出的MVC框架,也是AS3和Flex开发中广泛应用的一个框架。它以事件驱动为基础,结合了Service Locator、Singleton、Observer等设计模式,提供了Command、Event、Proxy、...

    Flex MVC框架 Cairngorm 学习笔记

    Cairngorm是一个轻量级的MVC(Model-View-Controller)框架,专为Adobe Flex应用程序设计。这个框架提供了一种结构化的方法来组织和管理Flex应用的复杂性,帮助开发者实现更好的代码复用、模块化和可维护性。在深入...

    Flex Cairngorm框架生成器

    8. **配置文件(Configuration)**:生成必要的配置文件,如flex-config.xml和 Cairngorm-specific的配置,以便正确地初始化框架。 9. **文档(Documentation)**:可能提供关于生成代码的简要说明,帮助开发者理解生成...

    Flex框架Cairngorm经典案例源码

    Cairngorm是Flex社区中流行的一种轻量级MVC(Model-View-Controller)框架,它提供了一种结构化的方法来组织和管理Flex项目的代码,从而提高开发效率和代码可维护性。 Cairngorm框架的核心组件包括: 1. **模型...

    Cairngorm-Flex.zip_Cairngorm_flex

    Cairngorm框架是Adobe Flex开发中的一种著名轻量级MVC(Model-View-Controller)框架,由Adobe公司的专业团队设计,旨在提高Flex应用程序的可维护性和可扩展性。这个框架的核心理念是通过分离业务逻辑、用户界面和...

    flex cairngorm 写的一个小例子

    Flex是Adobe公司开发的一款用于构建富互联网应用(RIA)的框架,它基于ActionScript和Flash Player或Adobe AIR运行时环境。Cairngorm是Flex社区中流行的一种轻量级MVC(模型-视图-控制器)设计模式实现,旨在帮助...

    flex mvc 架构图

    Flex MVC架构图是一种用于构建富互联网应用程序(RIA)的架构模型,主要应用于Adobe Flex开发中。Flex是一个开源框架,允许开发者使用MXML和ActionScript创建交互式的、基于Flash的用户界面。MVC(Model-View-...

Global site tag (gtag.js) - Google Analytics