Flex 开发架构(四): 去除FrontController 的Cairngorm

关键字: flex,cairngorm, frontcontroller

正如在使用Cairngorm时,视图中的每一个动作都播送一个事件,每个播送出去的事件都需要建立相应的命令代码来处理事件。并且需要在FrontController中对应他们的关系。例如下面的简单流程:

Loginvew.xml —> action login() —>dispatch LoginEvent —>Handled by LoginCommand —>mapping LoginEvent and LoginCommand in FrontController.

在不考虑商务层代码的情况下,当用户建立然后新的动作时,就需要建立2个新的代码,修改Controller代码。

那么如何简化Cairngorm,我的方法是去掉FrontController,取而代之的是Service Façade,其框架图如下所示:

 

 

在上图中,视图不再播送如何事件,而是直接调用Service Façade。而Service Façade则直接调用商务委托层与服务器端通讯(如Remote Object等),然后商务委托处理结果并更新Model Locator,最后Model Locator通过绑定(Binding)更新视窗中的结果。

 

看一下被改变的代码:

ServiceFacade.as:

 

package com.ny.flex.cairngorm.no_fc.service { import com.ny.flex.cairngorm.no_fc.vo.User; public class ServiceFacade { private static var _serviceFacade:ServiceFacade = null; public function ServiceFacade(privateClass:PrivateClass) { if(ServiceFacade._serviceFacade == null){ ServiceFacade._serviceFacade = this; } } public static function getInstance():ServiceFacade { if(_serviceFacade == null){ _serviceFacade = new ServiceFacade(new PrivateClass); } return _serviceFacade; } public function authenticate(user:User):void{ LoginDelegate.getInstance().authenticate(user); } public function getBuddyList():void{ BuddyListDelegate.getInstance().getBuddyList(); } } } class PrivateClass{}

 

ServiceFacade提供了对所有商务逻辑为一体的界面,视窗的行为仅仅调用façade,例如下面代码中的Login的动作。

Loginvew.xml

 

private function login():void{ if(Validator.validateAll(validators).length == 0){ var loginUser:User = new User(); loginUser.userName=username.text; loginUser.password=password.text; serviceFacade.authenticate(loginUser); }

 

 

 

 

 

函数 serviceFacade.authenticate(loginUser)如下:

 

public function authenticate(user:User):void{ LoginDelegate.getInstance().authenticate(user); }

 

ServiceFacade使用LoginDelegate 来真正实现Business Logic:

 

 

 

public function authenticate(user:User):void{ var responder:IResponder = new Responder(onResult_Authenticate,fault); var call:Object = service.authenticate(user); call.addResponder(responder); } private function _disibledevent= event.result as User; model.loginUser = authUser; model.viewStackSelectedIndex = 1; }


 

 

 

上面的authenticate(user) 实现于后台通讯并处理结果,更新Model Locator

 

下面是完整的LoginDelegate的代码:

 

package com.ny.flex.cairngorm.no_fc.service { import com.ny.flex.cairngorm.no_fc.*; import com.ny.flex.cairngorm.no_fc.vo.User; import mx.rpc.IResponder; import mx.rpc.Responder; import mx.rpc.events.ResultEvent; public class LoginDelegate extends BaseDelegate { private static var _loginDelegate:LoginDelegate = null; public function LoginDelegate(privateClass:PrivateClass){ if(LoginDelegate._loginDelegate == null ){ LoginDelegate._loginDelegate = this; } } public static function getInstance():LoginDelegate{ if(_loginDelegate == null){ _loginDelegate = new LoginDelegate(new PrivateClass); } return _loginDelegate; } public function authenticate(user:User):void{ var responder:IResponder = new Responder(onResult_Authenticate,fault); var call:Object = service.authenticate(user); call.addResponder(responder); } private function _disibledevent= event.result as User; model.loginUser = authUser; model.viewStackSelectedIndex = 1; } } } class PrivateClass{}

 

 

这个解决方案简化了Cairngorm的框架,使得代码更易于理解。而且,彻底摆脱了 无味的dispatcher,frontcontroller 和command。 编码效率会提高 并且易于调试。

 

但其弱点是显而易见的:它违犯了解耦的(就是使得设计程序耦合性尽可能的降低)设计规范,使得界面上的行为(Action)和Serivce Façade产生了耦合关系。

 

在最后一篇中我将讨论下一个Flex 开发的热点:Mate-标签化的框架。

发表评论

名 字:
Email:
验证码: