Cairngorm是Adobe公司推荐的Flex架构。
关于它的文档少的可怜,我只发现了这两个:
Developing Flex RIAs with Cairngorm microarchitecture
Cairngorm 架构包括六部分:Model Locator(共享数据),View(视图),Front Controller(前端控制器),Command (命令),Delegate(委托),Service(服务)。还有两个基础模块VO(数据对象),Event(事件)
Cairngorm流程大致如下:界面由View组成,View绑定Model Locater中的数据。客户在View中操作产生Event,Event被Front Controller所监听。Front Controller把Event绑定到Command,Command处理业务,创建Delegate,Delegate调用Service,Service远程访问Java。Java返回数据被Command得到并处理,更新Model Locater,View因为和Model Locater数据绑定,也会自动更新。详情见Cairngorm中文文档
这是我Flex代码的结构
VO
一般与服务器中domain里的对象一一映射。
需要注意的是转换时,数据类型的对应关系。
可参考转换表
BaseVO.as
package net.sw.album.vo { import com.adobe.cairngorm.vo.IValueObject; public class BaseVO implements IValueObject { [Bindable] public var id:Number; [Bindable] public var name:String; [Bindable] public var description:String; [Bindable] public var createtime:Date; } }
AlbumVO.as
package net.sw.album.vo { [RemoteClass(alias="net.sw.album.domain.Album")] public class AlbumVO extends BaseVO { [Bindable] public var owner_id:Number; [Bindable] public var authority:int; } }
Model Locater
储存所有界面共享的数据,有点象session,不同的是保存在客户端
model locater采用的是单例模式
AlbumModelLocater.as
package net.sw.album.model { import mx.collections.ArrayCollection; [Bindable] public class AlbumModelLocater { private static var albumModelLocater:AlbumModelLocater; public static const MYALBUMSTATE:String="myAlbumState"; public var ownerId:Number=1; public var albumId:Number; public var myAlbums:ArrayCollection; public var myFriends:ArrayCollection; public var picturesAC:ArrayCollection; ...... ..... public static function getInstance():AlbumModelLocater { if(albumModelLocater == null) { albumModelLocater = new AlbumModelLocater(); } return albumModelLocater; } } }
Front Controller
负责接收Event,并把Event和Command联系起来
AlbumController.as
package net.sw.album.controller { import com.adobe.cairngorm.control.FrontController; import net.sw.album.command.*; import net.sw.album.event.menuItemClickEvent.*; import net.sw.album.event.*; import net.sw.album.model.AlbumModelLocater; public class AlbumController extends FrontController { public function AlbumController() { initialiseCommands(); } public function initialiseCommands() : void { addCommand(DisplayMyAlbumEvent.EVENT_DISPLAY_MYALBUM,DisplayMyAlbumCommand); addCommand(AddAlbumEvent.EVENT_ADD_ALBUM,AddAlbumCommand); addCommand(ShowPhotoTileEvent.EVENT_SHOW_PHOTOTILE,ShowPhotoTileCommand); ...... ....... } } }
Delegate
都是结构化的东西,复制粘贴改几行代码就成了
AlbumDelegate.as
package net.sw.album.business { import com.adobe.cairngorm.business.ServiceLocator; import mx.rpc.IResponder; import mx.rpc.remoting.RemoteObject; import net.sw.album.vo.AlbumVO; public class AlbumDelegate { private var responder : IResponder; private var service : RemoteObject; public function AlbumDelegate(responder : IResponder ) { this.service = ServiceLocator.getInstance().getRemoteObject( "albumService" ); this.responder = responder; } public function findAlbumsByUserID() : void { var call : Object = service.getAll(); call.addResponder( responder ); } public function addAlbum(album:AlbumVO):void { var call : Object = service.saveAlbum(album); call.addResponder( responder ); } } }
Service
定义远程过程调用,这里使用的是RemoteObject
Services.mxml
<?xml version="1.0" encoding="utf-8"?> <!-- @version $Revision: 1.1 $ --> <cairngorm:ServiceLocator xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:cairngorm="http://www.adobe.com/2006/cairngorm"> <mx:RemoteObject id="albumService" destination="AlbumManager" showBusyCursor="true"> </mx:RemoteObject> <mx:RemoteObject id="photoService" destination="PhotoManager" showBusyCursor="true"> </mx:RemoteObject> </cairngorm:ServiceLocator>