Thinking in Java And Flex

Michael Niu’s Technical Weblog

Cut It Off-Cairngorm without front controller

As we know when you use Cairngorm, Every action of view need dispatch an event. Every dispatched event need to create command to handle the event. And you have to add the mapping them in the frontcontroller. For example:

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

When you create any new action , you have to create 2 classes and modify front controller, assume the business logic code is same .

So How to simplify Cairngorm? My solution is cut of frontcontroller. The architecture is :

As above diagram show, The view will not dispatch any event. It will service façade directly. The façade will call business delegate to communicate with the server side solution(i.e. remote object). Then the delegate will handle the result and update Model locator. Finally Model locator will update the result view by Binding.

Lets see the code ;

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 provides unify interface of all business logic. And the action of view will only call the façade . for example login action in 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);

}

}

 

 

Lets see the function serviceFacade.authenticate(loginUser):

public function authenticate(user:User):void{

LoginDelegate.getInstance().authenticate(user);

}

 

 

It calls the function “authenticate(user)” in 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 onResult_Authenticate(event:ResultEvent)

:void{

var authUser:User = event.result as User;

model.loginUser = authUser;

model.viewStackSelectedIndex = 1;

}

 

 

As above code shows the delegate will call the data source , handle the result and update model locator.

Lets see the completely code from LoginView to LoginDelegate:

BaseView.mxml:

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{}

The façade will locate the concrete Business delegate method :

LoginDelegate.as:

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 onResult_Authenticate(event:ResultEvent):void{

var authUser:User = event.result as User;

model.loginUser = authUser;

model.viewStackSelectedIndex = 1;

}

}

}

class PrivateClass{}

 

 

This solution simplify Cairngorm framework. And It makes everthing understandable. But the shortage is obviously. It broke some design patten rules Decouple the application as much as possible. It couple the action to the Service Façade.

Lets move the next part:Mate-Tag Base Framework,

  

July 28, 2008 - Posted by | Flex

1 Comment »

  1. […] So  if you have to use  cairngorm   use  my solution  Cairngorm without FrontContoller. […]

    Pingback by Mate-Tag Base Framework « Thinking in Java And Flex | July 30, 2008 | Reply


Leave a comment