Spring ActionScript: Café Townsend sample application

ActionScript, Air, Design Patterns, Domain-Driven Design, Flash, Flash Builder, Flex, Flex Builder, Inversion of Control, Spring ActionScript Add comments

A new Spring ActionScript sample application is now available. This is the Café Townsend application, originally created as a sample application for the Cairngorm framework, that we ported to Spring ActionScript. This should make it easier to compare this implementation with the implementations of some of the other frameworks.

Open the Café Townsend sample.
(Be sure to check the source by right-clicking and choosing "View Source" from the context menu, click here to go to the source directly.)

Download the Flex/Flash Builder project and sources.

Discussion

In what follows, we will discuss the implementation details and motivate certain choices made in this design.

Package Structure

The first thing you might notice is the package structure, that might seem a bit odd at first since it is different from what most frameworks use or prescribe. This example follows the Layered Architecture, described by Eric Evans in the book Domain-Driven Design: Tackling Complexity in the Heart of Software (recommended reading). This architecture makes it easy to detect and apply the different layers of the application and forces us somewhat to have a clean separation of the responsibilities of each layer.

The layered architecture consists of four layers, as shown on the image below:

  • Presentation Layer: contains the user interface (the view component and in this example the presentation models)
  • Application Layer: coordinates the application and forms a communication channel between the UI and the domain
  • Domain Layer: the core of the software. This layer defines the entities and repositories/services that form the business logic of the application. For the most part only the interfaces for the services will be written here. This layer does not contain any implementation details.
  • Infrastructure Layer: provides implementation details for all other layers. Concrete implementations of services will be put here.

Note that it is certainly not needed to structure your application like this. Spring ActionScript does not impose or prescribe this structure, but we certainly think it is useful and wanted to introduce it in this example. Also note that while we have applied this architecture as packages in the same application, you might want to create different swc's or libraries for each of these layers so that they can easily be reused.

Presentation Layer & Presentation Models

This example uses the Presentation Model (PM) as the main presentation pattern for the UI layer. The PM allows us to extract all state and controller logic for the view into a separate class that is view agnostic. A view component contains a reference to its corresponding PM and delegates all UI actions to it. The view component can either instantiate the PM directly, or it can be given one, either by a parent component or by having it "injected" by the Spring ActionScript framework. The process of automatically injecting properties into a (view) component is known as "Autowiring" in Spring ActionScript. Note that since the PM is not a UI component and does not know anything about the view, it can be easily unit tested.

An example of autowiring can be found in the EmployeeLogin.mxml class:

Actionscript:
  1. [Autowired]
  2. [Bindable]
  3. public var presentationModel:EmployeeLoginPresentationModel;

The PMs used in this example will either delegate directly to the business logic (for instance for loading the employees) or will delegate to the Application Layer (for instance for logging the user out of the application). Here again, there is no strict rule to follow, but you can decide for your own what approach seems the bests.

Note that autowiring is disabled by default. This is because in bigger applications, there might be a significant performance hit when autowiring is used. It is adviced to finetune the autowiring by configuring the autowire processor to include or exclude certain classes. To enable autowiring, simply add the following to the XML configuration:

XML:
  1. <object id="autowiringStageProcessor" class="org.springextensions.actionscript.stage.DefaultAutowiringStageProcessor"/>

Application Layer

In some cases, the UI will delegate responsibilities to the Application Layer. Since the UI does not know about this layer, it needs a loosely coupled way of communicating with it. The communication channel that provides this capability in Spring ActionScript is the EventBus. It is implemented on top of Flash's event dispatching capability and forms a centralized medium for component and layer interaction.

In the example, the code behind the Logout button will dispatch an event via the EventBus. The application controller listens for this event and will handle it by invoking the logout method on the authentication service. Notice that the application controller takes the authentication service as a constructor argument and that the service is typed to the interface IAuthenticationService. The actual instance is provided in the (XML) configuration, were both the application controller and the authentication service and defined and linked to eachother.

Notice that the application controller does not explicitely listen for the logout event. Instead, it is sufficient to create a method and annotate it with the [EventHandler] metadata. Spring ActionScript will then introspect the controller, pick up all annotated methods and link them automatically with the event received from the EventBus.

Here's what the logout method looks like in the application controller:

Actionscript:
  1. [EventHandler]
  2. public function logout():void {
  3.   var operation:IOperation = _authenticationService.logout();
  4.   operation.addCompleteListener(logout_completeHandler);
  5. }

Notice that the name of the logout method corresponds to the event being dispatched, namely "logout" (see the ApplicationEvents class for that). You can however also choose the name of this method as you like and specify the name of the event as an attribute of the EventHandler metadata.

As with autowiring, the processing of the EventHandler metadata is not enabled by default. If you want to use this in your application, simply add the following to the XML configuration:

XML:
  1. <object id="eventHandlerProcessor" class="org.springextensions.actionscript.ioc.factory.config.EventHandlerMetaDataPostProcessor"/>

For more information on the EventBus, please refer to the documentation.

Domain Layer

The domain for this application is extremely simple. All it contains is an Employee entity and an employee service in the form of the IEmployeeService. Except for the actual entities of the domain, this layer does not contain any implementation details for the services it provides, but merely defines the interfaces for those services.

Infrastructure Layer

The infrastructure layer is where the technical details of the applications live. This layer provides the actual implementation of the services found in the other layers. Depending on the different contexts the application needs to be able to run in, you might provide different implementations of the services here. The implementations used in the application can then be defined the a Spring ActionScript Application Context. As an example, think of an application that needs to be able to connect to a set of services using Remote Objects in one scenario and needs to connect to a set of Webservices in another scenario. If we provide both implementations, we can easily reconfigure the application by changing the XML configuration of the application context.

Application Context

Once we have all components, we can bundle them together and prepare them to be used in the application. By doing this, we are configuring the context of the application. In Spring ActionScript this is done by instantiating a FlexXMLApplicationContext (in case you are working with Flex).

The application context in this example is configured using XML, but it could just as easily be configured using an MXML configuration. Both approaches have there pros and cons and you should decide what fits best for you project.

Looking at the Main.mxml class, which is the entry point of the application, we can see that a FlexXMLApplicationContext is instantiated and given the path to the external XML file (application-context.xml) that forms the application context's configuration. Now all we need to do is wait for the context to load before starting the application.

Conclusion

This example contains significantly less code than the original Cairngorm version. This is mainly because Spring ActionScript does not impose any strict architectural rules and provides the developer with plenty of choice for architecting things that best fit the application being developed. What might work in application A might not necessarily work well for application B or C. Being given so much freedom and choice might feel awkward at first, but you will notice that this is actual a good thing and you will benefit greatly from it.

If you have any remarks on this post, please leave them in comments or contact me. Whether they are errors, things that are unclear, or general questions... all feedback is welcome.

General information and document about Spring ActionScript can be found at http://www.springactionscript.org/

Related articles:


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

11 Responses to “Spring ActionScript: Café Townsend sample application”

  1. Wim Deblauwe Says:

    Really nice structure. I wish I had something simular when programming Swing a few years ago.

    One detail: can you add the code to dispatch the logout event in the blog post. I think it would be a bit easier to follow along with the blog post for the lazy like me who do not download the sources :)

    keep up the good work!

    regards,

    Wim

  2. spiritj Says:

    really excellent work.
    One confusing here:
    while everything running fine in ur micro-container,but in ur “EmployeeList.mxml”,in the area of private properties declaration,
    I’m wondering why “[Autowired]” not directly worked on the property “_presentationModel” instead of its getter function?code given below:

    //[Autowired] <-why not work?
    private var _presentationModel:EmployeeListPresentationModel;

    [Autowired] //why it work? wot's the meaning of "autowired a (getter)funtion"?
    [Bindable(event="presentationModelChange")]
    public function get presentationModel():EmployeeListPresentationModel {
    return _presentationModel;
    }

    //presentationModel using here

    Hoping ur reply

    regards,

    spiritj

  3. spiritj Says:

    Hi,Christophe:
    i found that private property can’t be autowired,right?
    but my another question is why u autowire the getter but not the setter,
    any different? Does getter autowiring means unconditionally autowired?

    waiting ur reply…

    regards,

    spiritj

  4. Christophe Says:

    Hi spiritj,

    since we can’t read the private variables of an object via reflection, we need to annotate a public variable which can then be autowired. It does not really matter if you annotate the getter or the setter, since these are treated as 1 accessor with read/write properties.

    regards,
    Christophe

  5. Murug Says:

    Hi,

    Can any one give me the link to donwload the source code of cairngorm — Cafe Townsend application.

    Muruga

  6. Christophe Says:

    Hi Murug, I think you can download the Cairngorm sources here :http://www.cairngormdocs.org/exampleApps/CafeTownsend.zip

  7. Mike Hemelberg Says:

    Hi Christophe,

    Awesome post. Is it OK to add style names to presentation model classes?

    For example,

    public var price:Number;
    public var priceStyleName:String;
    public var priceOverStyleName:String;
    public var titleStyleName:String;

  8. Flash video news Says:

    Thanks for publishing this. the layered architecture diagram was helpful. I just downloaded the source code. time to start playing! Thanks again.

  9. Ceas Says:

    I know this is a small issue but if my understanding is correct about the architecture layers and the diagram, each layer shouldn’t have reference to the layer above it. If this is true, why are concrete services in infrastructure implementing interfaces from from the domain layer?

  10. Christophe Says:

    Hi Ceas, that’s a good remark. The schema is a bit unclear in that sense since the infrastructure layer should really be drawn vertically next to the other tiers.

  11. Wagner Francisco Mezaroba. Says:

    Hi Christophe,

    First of all, I’d like to say that Spring Actionscript is an amazing framework, it works very well and I have being using it for some months with success.

    I’ve seen this post some months ago and I’m developing an application using the suggested approach. But I have some problems with it and I’d like to hear your opinion about them.

    The first one is the way you deal with the models. In your sample, EmployeeListPresentationModel is injected by the container and this object is responsible for instantiating the EmployeeDetailPresentationModel (which is not injected). The problem for me is that I usually need to access services and beans managed by the container in my Detail classes (like EmployeeDetailPresentationModel). For example, in my app I need to create a Travel and this Travel has an Itinerary. In order to create this Itinerary (or find an existent one) I need to use another service. To solve this, when I’m instantiating my Detail class I usually ask the container for an instance of the Detail class (I created a factory that has an applicationContext). But maybe there is a better solution. How do you handle this?

    Another question is, why don’t you save the employee in the EmployeeDetailPresentationModel class? The way you have done works very well in your example. But if I needed to show the window to save employees in a different place? I would have to create listeners for the Detail class again? Wouldn’t it be better if the Detail class were able to save the employee?

    And the last question is… you said that in big applications it might be necessary to disable autowiring. My question is… if I’m using too much this resource, my application will be slow just in the beggining? Or every time I need to inject an autowired class it will be more slow?

    Thanks in advance, I really appreciate your work.

Leave a Reply

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in