Realtime hit counterweb stats

Archive for the 'Adobe AIR' Category

Flex Mojos 3.2.0 Released

Monday, May 18th, 2009

Sonatype recently released the latest version of Flex Mojos, which is now at version 3.2.0.

This latest update is a big step forward for Flex / AIR Developers managing their project builds and dependencies with Maven 2 as the updates are focused around unit testing support improvements; including support for headless mode on Linux based CI servers and, more importantly, a fix for running automated unit tests in multi-module builds; which was a big head scratcher for me about a month ago!

Below is a list of what I feel are the most significant updates in 3.2.0:

  • Added support for SWF optimization
  • Multi-module builds now run tests correctly across projects
  • Changes to the way flex-mojos launches flash player when running test harness
  • Long-running flexunit tests no longer cause the build to fail.
  • Fix to NullPointerException during flex-mojos:test-run goal
  • You can view the complete list of release notes here.

    Cairngorm Abstractions: Business Delegates

    Thursday, May 7th, 2009

    In Part 1 of Cairngorm Abstractions I discussed the common patterns which can be utilized in a design to simplify the implementation of concrete Cairngorm Commands and Responders. Applying such patterns can be leveraged to help facilitate code reuse and provide a maintainable, scalable architecture, as, in doing so the design will ultimately ensure reuse as well as remove redundancy.

    In this post I will describe the same benefits which can be gained by defining common abstractions of Business Delegates.

    Business Delegate Abstractions
    A Business Delegate should provide an interface against the service to which it references. This can be viewed as a one-to-one relationship whereas the operations and signatures defined by a Service, beit an HTTPService, WebService, RemoteObject, DataService etc. would dictate the Business Delegate’s API.

    However, a rather common mistake I often find is that many times Business Delegates are defined in the context of the use case which invokes them, rather than the service from which they provide an interface against.

    Correcting this is quite simple: refactor the current implementation to follow the one-to-one relationship model between a Service and Business Delegate.

    So for instance, if your applications service layer specifies a “UserService”, your design should essentially have only one Business Delegate API for that Service. All of the operations provided by the “UserService” would be defined by an “IUserServiceDelegate” interface which would enforce the contract between the “UserService” and concrete Delegate implementations, regardless of their underlying service mechanism.

    In this manner clients (delegate instances) can be defined as the abstraction (IUserServiceDelegate) and obtain references to concrete Business Delegate instances via a Delegate Factory, and as such remain completely transparent of their underlying service implementation.

    This could be implemented as follows:

    var delegate:IUserServiceDelegate;
    delegate = DelegateFactory.createUserServiceDelegate( responder );
    // invoke delegate …

    Abstract Delegates
    Perhaps the most common design improvement which can be made to improve the implementation and maintainability of Business Delegates is to define proper abstractions which provide an implementation which is common amongst all Business Delegates. Additionally, in doing so you will remove a significant amount of redundancy from your design.

    For example, if you compare any two Business Delegates and find they have practically the exact same implementation, that is an obvious sign that a common abstraction should be defined.

    Consider the following Business Delegate implementation:

    public class SomeDelegate
    {   
      private var _service:RemoteObject;
      private var _responder:IResponder;
       
      public function SomeDelegate(responder:IResponder)
      {
          _service = ServiceLocator.getInstance().
                     getRemoteObject( Services.LOGIN_SERIVCE );
          _responder = responder;
      }
       
      public function methodA(arg1:String, arg2:int) : void
      {
          var call:AsyncToken = _service.methodA( arg1, arg2);
          call.addResponder( _responder );
      }

      public function methodB(arg:Boolean) : void
      {
          var call:AsyncToken = _service.methodB( arg );
          call.addResponder( _responder );
      }

      public function methodC() : void
      {
          var call:AsyncToken = _service.methodC();
          call.addResponder( _responder );
      }
      …
    }

    The above example may look familiar, and when given just a bit of thought as to it’s design it becomes apparent that there is quite a bit of redundancy as every method essentially contains the same implementation code. That is, an AsyncToken is created, referencing the operation to invoke against the service, and a reference to the responder is added to the token.

    The overall design would benefit much more by refactoring the commonality implemented across all Business Delegate methods to an abstraction, which in it’s simplest form could be defined as follows:

    public class AbstractRemoteObjectDelegate
    {   
      protected var service:RemoteObject;
      protected var responder:IResponder;

      public function AbstractRemoteObjectDelegate(serviceId:String,
                                                responder:IResponder)
      {
          this.service = ServiceLocator.
                         getInstance().getRemoteObject( serviceId );
          this.responder = responder;
      }

      protected function invoke(methodName:String, …args) : void
      {
          var operation:Operation = service[ methodName ];
          operation.arguments = args;
               
          var call:AsyncToken = operation.send();
          call.addResponder( responder );
      }
    }

    By defining a basic abstraction, the original implementation could then be refactored to the following:

    public class SomeDelegate extends AbstractRemoteObjectDelegate
    {   
      public function SomeDelegate(responder:IResponder)
      {
          super( Services.LOGIN_SERIVCE, responder );
      }
       
      public function methodA(arg1:String, arg2:int) : void
      {
          invoke( "methodA", arg1, arg2 );
      }

      public function methodB(arg:Boolean) : void
      {
          invoke( "methodB", arg );
      }

      public function methodC() : void
      {
          invoke( "methodC" );
      }
    }

    The same basic abstractions could easily be defined for HTTPService, WebService and DataService specific Business Delegates (in fact I have a library of Cairngorm extensions which provides them; planning on releasing these soon). Pulling up common implementation code to higher level abstract types also simplifies writing tests against concrete Business Delegates as the abstraction itself would need only to be tested once.

    There are many more Business Delegate abstractions I would recommend in addition to what I have outlined here, in particular configuring Delegate Factories via an IoC Container such as SAS, however I would first suggest taking a good look at your current design before adding additional layers of abstraction, and the most appropriate place to start would be to define abstractions which encapsulate commonality, promote reuse and remove redundancy.

    Cairngorm Abstractions: Commands and Responders

    Tuesday, April 21st, 2009

    It is quite common to find a significant amount of code redundancy in Flex applications built on Cairngorm. This is by no means a fault of the framework itself, actually quite the contrary as Cairngorm is designed with simplicity in mind; opting to appropriately take a less-is-more approach in favor of providing a more prescriptive framework which only defines the implementation classes necessary to facilitate the “plumbing” behind the framework. Everything else is really just an interface.

    With this amount of flexibility comes additional responsibility in that developers must decide what the most appropriate design is based on their applications specific context. Moreover, as with any design there is never a truly one size fits all approach which can be applied to any problem domain; there are really only common patterns and conventions which can be applied across domains and applications. This IMHO is what had allowed the framework to be a success and it is important to understand that this simplicity also requires developers to give their designs the same attention one would to any Object Oriented design.

    However over the years I have found a significant amount of redundancy found in Flex applications built on Cairngorm. This appears to be (more often than not) the result of developers implementing Cairngorm examples verbatim in real world applications, and in doing so failing to define proper abstractions for commonly associated concerns and related responsibilities. The most common example of this is the typical implementation of Commands, Responders BusinessDelegates and PresentationModel implementations.

    For some of you this may all seem quite obvious, and for others hopefully this series will provide some insight as to how one can reduce code redundancy across your Cairngorm applications by implementing abstractions for common implementations.

    This topic will be a multi-part series in which I will provide some suggestions surrounding the common patterns of abstractions which can be implemented in an application built on Cairngorm, with this first installment based on common abstractions of Cairngorm Commands and Responders. Other areas in future posts will cover Business Delegate and Presentation Model abstractions. So let’s get started…

    Command Abstractions
    First let’s begin by looking at what is arguably the simplest abstraction one could define in a Cairngorm application to simplify code and eliminate areas of redundancy – Command abstractions. This example assumes the concern of mx.rpc.IResponder implementations is abstracted to a separate object. For more on this subject see my post regarding IResponder and Cairngorm.

    A traditional Cairngorm Command is typically implemented as something to the extent of the following:

    import com.adobe.cairngorm.commands.ICommand;
    import com.adobe.cairngorm.control.CairngormEvent;

    public class Command implements ICommand
    {
      public function execute(event:CairngormEvent):void
      {
        var evt:SomeEvent = event as SomeEvent;
               
        // ModelLocator look-up and common references
        ModelLocator.getInstance()
    }
    }

    The problem with the above Command implementation is that it results in numerous look-ups on the ModelLocator Singleton instance in every execute implementation which needs to reference the ModelLocator.

    A simpler design would be to define an abstraction for all commands which contains this reference. as in the following:

    import com.adobe.cairngorm.commands.ICommand;
    import com.adobe.cairngorm.control.CairngormEvent;
       
    /**
     *
     * Defines an abstraction of common references from
     * which concrete ICommand implementations can
     * inherit
     *
     */

    internal class AbstractCommand implements ICommand
    {
      // define common reference to ModelLocator
      // implementation
      protected static var modelLocator:ModelLocator
                           = ModelLocator.getInstance();

      // Force concrete command implementations to
      // override execute
      public function execute(event:CairngormEvent) : void
      {
        throw new Error( "Abstract operation…" );
      }
    }

    As in any OO system there are many benefits to defining abstractions and a good design certainly reflects this. For example, just by defining a very basic abstraction for all Commands we have now eliminated the number of look-ups on the ModelLocator for every Command in the application as well as redundant imports. By defining an abstraction for common references your code will become easier to read and maintain as the number of lines of code will certainly become reduced.

    Commands are by far the easiest to create an abstraction for as most commands will typically reference the ModelLocator, and if so they could do so simply by extending an AbstractCommand, if not they would implement ICommand as they traditionally would.

    So the first example could now be refactored to the following:

    import com.adobe.cairngorm.control.CairngormEvent;

    public final class Command extends AbstractCommand
    {
      override public function execute(event:CairngormEvent):void
      {
        var evt:SomeEvent = event as SomeEvent;
        // modelLocator…
      }
    }

    You could take these abstractions a step further and define additional abstractions for related behavior and contexts, all of which would also extend the AbstractCommand if a reference to the applications ModelLocator is needed.

    Responder Abstractions
    Now let’s take a look at an abstraction which is much more interesting – Responder abstractions. In this example we will focus on the most common Responder implementation; mx.rpc.IResponder, however the same could easily apply for an LCDS Responder implementation of a DataService.

    A separate RPC responder could be defined as an abstraction for HTTPServices, WebServices and RemoteObjects as each request against any of these services results in a response of either result or fault, hence the IResponder interface’s contract.

    For example, consider a typical Responder implementation which could be defined as follows:

    import mx.rpc.IResponder;
    import mx.rpc.events.FaultEvent;
    import mx.rpc.events.ResultEvent;
       
    public class SomeResponder implements IResponder
    {      
      public function result(data:Object) : void
      {
        // redundant cast operation
        var result:ResultEvent = data as ResultEvent;
               
        // Redundant ModelLocator lookup and references…
        // ModelLocator.getInstance()…
      }

      public function fault(info:Object) : void
      {
        // Redundant cast operation
        // Doesn’t provide a centralized place for
        // global service exception handling
        var fault:FaultEvent = info as FaultEvent;
               
        // Redundant ModelLocator lookup and references…
        // ModelLocator.getInstance()…
      }
    }

    By defining a Responder abstraction each concrete Responder implementation would result in significantly less code as the redundant cast operations could be abstracted, and, as with Command Abstractions, a convenience reference to the application specific ModelLocator could also be defined. Moreover, a default service fault implementation could be defined from which each service fault could be handled uniformly across the application.

    Thus we could define an abstracttion for RPC Responders as follows:

    import mx.rpc.IResponder;
    import mx.rpc.events.FaultEvent;
    import mx.rpc.events.ResultEvent;
       
    /**
     *
     * Defines an abstraction of common references and
     * functionality from which concrete IResponder
     * implementations can inherit
     *
     */

    internal class AbstractRPCResponder implements IResponder
    {   
      protected static var modelLocator:ModelLocator
                           = ModelLocator.getInstance();
               
      // Provides a default implementation of
      // mx.rpc.IResponder.result(); which
      // handles casting to a ResultEvent
      public function result(data:Object):void
      {
        var result:ResultEvent = ResultEvent( data );
        resultResponse( result );
      }
           
      // provide default implementation of
      // mx.rpc.IResponder.fault(); which
      // handles casting to a FaultEvent
      public function fault(info:Object) : void
      {
        var fault:FaultEvent = FaultEvent( info );
        faultResponse( fault );
      }
           
      // Force concrete implementation to override
      // resultResponse
      public function resultResponse(result:ResultEvent):void
      {
        throw new Error( "Abstract operation" );
      }
           
      // Provides default service exception handling
      // universally across all Responder implementations.
      // Concrete implementations can also override this
      // method if specific fault handling needs to be
      // implemented
      public function faultResponse(fault:FaultEvent):void
      {
        // implement default service exception handling
      }
    }

    We could now refactor the original Responder implementation to the following simplified implementation:

    import mx.rpc.events.ResultEvent;
       
    public final class SomeResponder extends AbstractRPCResponder
    {      
      override public function resultResponse(result:ResultEvent):void
      {
        // modelLocator…
      }
    }

    As you can see just be pulling up common references and functionality to just two abstractions we can significantly remove redundancy from all Commands and Responders. As such this allows designs to improve dramatically as it allows for the isolation of tests and limits the amount of concrete implementation code developers need to sift through when working with your code.

    It is important to understand that a design which is built in part on Cairngorm must still adhere to the same underlying Object Oriented Design principles as any other API would, and in doing so you will end up with a much simpler design which can easily scale over time.

    Flex Quick Tip: ASDoc Package comments

    Wednesday, March 25th, 2009

    Documenting ActionScript elements such as a Class, Interface, method, property, event, style and so forth with ASDoc is a rather simple and straightforward process. However one element which is a bit more tricky to document with ASDoc is package declarations.

    Determining how to document package declarations is a bit more complicated than say, documenting classes as there is not a specific ASDoc tag intended for documenting packages in source code form. To do so one might assume to simply add an ASDoc comment to a package declaration, such as the following:

    /**
     *
     * Package comment….
     *
     */

    package foo {

    However the above will not generate ASDoc source documentation; it will simply be ignored by the asdoc compiler.

    In order to document packages you need to specify the -package argument to the asdoc compiler. This is specified in the form:
    -package <package-name> '<package-comment>'

    -package foo "Foo package comment..."
    -package foo.bar "Foo Bar package comment.."

    In general I think most developers would prefer not to specify any kind of source file documentation via a compiler argument as this type of metadata ideally should be defined as an annotation (in the documentation sense of the word) to the actual source file itself, however if you find a need to document packages the -package compiler option will do the job.