Welcome!

Adobe Flex Authors: Liz McMillan, RealWire News Distribution, Maureen O'Gara, Yakov Fain, Keith Swenson

Related Topics: Adobe Flex

Adobe Flex: Article

Developing Adobe Flex Rich Internet Applications with Cairngorm Microarchitecture

Using the Cairngorm Store sample application

Keeping State on the Client
One key shift in mindset when you move from the development of web applications to rich Internet applications is that the client is stateful.

Web application developers are all too familiar with the stateless request/response approach. Therefore, they have created various approaches for maintaining state on the client. Whether you continually stuff data into an HTTP request as the client and the server exchange pages, or you use URL encoding or cookies to keep some limited state information on the client, or you take advantage of abstractions of these features such as J2EE sessions, the typical application developer's is to maintain state on the server, and make it available to the client.

With RIAs however, web application developers can break free from the shackles of HTTP request and response. No longer do you have to concoct solutions for the stateless client because the client is indeed stateful. If you have been building desktop or rich-client applications with technologies such as Swing or AWT, for instance, you'll shrug your shoulders right now because all of this will sound all too familiar - it is.

Difference Between State and the Model in MVC
Many developers are familiar with the concept of MVC or Model/View/Control in application development, and wonder where state fits into this discussion. Quite simply, the state is the model. As obvious as this may sound, it presents some further common challenges to solve in the implementation of the model in an RIA.

First, resist the opportunity to scatter state all over your application as strings, numbers, Booleans, and all manner of other primitive objects. It is not my purpose here to advocate best practice object-oriented development. Indeed, that you accept the benefits and practice the principles of OO are almost prerequisites to understanding this article.

However, I strongly advocate that the client hold the data - as state, model, or whatever you want to call it, as objects that have semantic meaning. What is semantic meaning in this context? I mean that if you sell fly-fishing flies online, your object model should include "flies," "patterns," "hooks," and "hackles." If you sell mortgages, your object model should include "products," "rates," "repayments," and "terms." If you sell maps, your object model likely includes "routes," "waypoints," "points of interest," and "gas stations."

Synchronizing Client and Server State
One challenge is relatively unique to the stateful client of a rich Internet application: The state on the client usually reflects the state held on the other side of the wire, in the server middleware. Let's examine this design problem some more. In server-side application development, one key challenge is that state often sits within two tiers of an application architecture: the business tier and the integration tier.

The integration tier usually contains databases, mainframes, message queues, ERP solutions, CRM systems, and other enterprise information systems that hold data on the objects and process particular to a business domain.

In enterprise application development, these systems are typically aggregated and presented to users through a middleware tier, also called the business tier. Many solutions address some of the challenges of keeping state consistent across the two tiers. First of all, the representation of data in these tiers may be dramatically different. For instance, the entities, relationships, views, and queries that exist in a relational database solution must be mapped from a relational model in a database to an object model in the middleware business tier. You can use technologies such as Enterprise JavaBeans, Hibernate (H8), and ADO.NET to map data across these architectural tiers.

Irrespective of the solution chosen, the application developer assumes a great deal of responsibility in ensuring the consistency of state across these tiers. As soon as you keep the same information in two places, there is a risk that changes to it in one place are not reflected in another place, or that changes in one place overwrite changes in another place. Suddenly, the developer must care about concurrency, locking, transactions, rollback, and other approaches for ensuring that the model is consistent in these different places in the architecture.

As RIA developers, you are abstracted from the complexities between the business and integration tier; your concerns focus more on how to ensure that the model in the business tier is consistent with the model in the presentation tier.

You can achieve this most easily by ensuring that you have a consistent object model on the client and server, and that you minimize the effort required to keep these object models synchronized.

Introducing the Value Object / Data Transfer Object Pattern
Whenever you want to represent the value of things on the client, you can do worse than to create classes or objects that represent the values of those things. For instance, in Cairngorm Store, one thing that you must represent is the products in our store. Each product has a number of attributes: name, description, price, an associated image for the detailed view, and an associated thumbnail image for the catalog view.

These value objects play a dual role in a rich Internet application, however. In addition to keeping the value of an item on the client, they are useful structures with which you can exchange or transfer data between different tiers in an application. In server-side development, consider a strategy in which you query a database using SQL, receive a result set, and then transform that result set into a collection of value objects representing the things you have pulled from the database.

By passing collections of these value objects between application tiers, you insulate each tier of the application from the underlying implementation of its neighboring tiers. The middleware need not care whether these value objects were created from a SQL query, stored procedure call, message queue, or web service call. By reusing these value objects, you decouple architecture by transferring data between tiers as objects with business meaning ("Products," "Fish," "Maps") rather than technical meaning ("RecordSets," "ResultSets," "Data Sets"). This has led to calling the Value Object pattern the Data Transfer Object pattern instead.

We conceived Cairngorm before the term data transfer object (DTO) became popular, so I call the business objects value objects or VOs.

For example, look at the VOs in the Cairngorm Store application, which reside in the org/nevis/cairngorm/samples/store/vo package:

class org.nevis.cairngorm.samples.store.vo.ProductVO implements ValueObject, Comparable
{
public static var registered:Boolean = Object.registerClass( "org.nevis.cairngorm.samples.store.vo.ProductVO", ProductVO );

public var id : Number;
public var name : String;
public var description : String;
public var price : Number;
public var image : String;
public var thumbnail : String;
}

This is not rocket science. The ProductVO is nothing more than a collection of attributes that describe what makes a Product a product. Whenever you keep state on the client about Products, keep it as instances of the ProductVO. If the application must know what the "currently selected product" is, store that information on the client as a ProductVO instance. If the application needs to retain a list of the products in a customer's shopping cart, store that information on the client as a list of ProductVO instances.

Furthermore, if you have to transfer products from the server (and we do, but more on that later) or if you ever have to transfer products back to the server, transfer that data back and forth as value objects. Others might say that you're using data transfer objects, because you are. They're the same thing, remember?

Keeping a Consistent Object Model Between Flex and Java
When you develop middleware, a key artefact from the development process is typically a well-defined object model. In J2EE application development, there is often a package of Java value objects already on the server that correspond exactly to the value objects required on the client.

In this case, the Flex server does some pretty significant heavy lifting for the application. If you want to pass ActionScript value objects into Java, Flex can automatically create the equivalent Java objects on the server side for those objects that you placed on the client side. Similarly, as the Java middleware returns Java value objects to the client, Flex ensures that by the time the RIA uses these objects on the client side, Flex has already translated them into the equivalent ActionScript value objects.

Even more powerfully, if the objects are not just single value objects but complex graphs of value objects, Flex does all the work associated with traversing the graph of objects - not only translating the objects but maintaining the relationships between objects. Thus, when you have a ShoppingCartVO that contains a list of ProductVO objects, and each ProductVO contains a list of AddressVO objects (for delivery and invoice addresses) and an optional DiscountVO object, Flex ensures that the composition of objects stays consistent when passing it between the RIA client and middleware server.

To allow Flex to map between client-side and server-side value objects, you must provide some hints to the Flex server about the relationship between the classes. In Cairngorm, you achieve this by advocating that each and every instance of a value object class contains the following:

public static var registered:Boolean =
Object.registerClass( "org.nevis.cairngorm.samples.store.vo.ProductVO", ProductVO );

This line ensures that a ProductVO class on the client maps to the Java class ProductVO.java that resides in the package org.nevis.cairngorm.samples.store.vo.ProductVO on the server.

Using XDoclet2 with ActionScript
XDoclet2 is a java-driven ActionScript code generator. Joe Berkowitz of Allurent created a labor-saving, open-source project for creating ActionScript value objects from their Java counterparts. You can find more information on the project, including a link to the source code on SourceForge, at www.allurent.com/joeb/xdoclet2.

To recap, value objects ensure that you do the following:

  • Adhere to the best practice of representing client-side data with a meaningful object model
  • Maintain a consistent object model on the client and server
  • Leverage the capabilities of the Flex server to translate value objects between Java and ActionScript as they "cross the wire" between client and server
Getting data to the client that is consistent with the server is only the first part of the problem. What do you do with the client-side data and where you keep it to enable you to accomplish this task?

More Stories By Steven Webster

Steven Webster is the practice director for Rich Internet Applications at Adobe. Previously, he was the technical director at iteration::two, a world-leading Rich Internet Application consultancy based in Edinburgh, Scotland. Webster is the author of Reality J2EE: Architecting for Flash MX and coauthored ActionScript 2.0 Design Patterns for Rich Internet Applications (ActionScript 2.0 Dictionary) and Developing Rich Clients with Macromedia Flex with Alistair McLeod. Steven speaks regularly at conferences and user group meetings on technical and business aspects of RIAs. Steven is the core contributor to the open-source Cairngorm project, a microarchitecture for RIAs based on J2EE patterns which was innovated by iteration::two over a number of Flash and Flex RIA developments.

Comments (2) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
Sys-Con Italy News Desk 04/04/06 10:44:53 AM EDT

This series presents an open-source architectural framework to Flex developers called Cairngorm. In this series I explain the thought leadership behind Cairngorm, the design challenges that Adobe feels Cairngorm addresses best, and the projects for which Cairngorm is an appropriate skeleton for development.

SYS-CON India News Desk 04/03/06 05:58:01 PM EDT

This series presents an open-source architectural framework to Flex developers called Cairngorm. In this series I explain the thought leadership behind Cairngorm, the design challenges that Adobe feels Cairngorm addresses best, and the projects for which Cairngorm is an appropriate skeleton for development.