Miracle of Data Transfer Objects

If you had only one hour in Paris, what would you do?

I, for one, would walk around Notre-Dame, and the point I am going to make is about Flex:

If I could pass just one Flex advice that would be: Use Data Transfer Objects.

Use Data Transfer Objects and NOT the dynamic Objects, and NOT the XML to pass data between your server and Flash tiers. If you are working with a Java Server, make your Java (methods) accept/return custom classes and NOT Map objects.

With this keystone your architecture will be reliable and performing. You will save tons of time and energy. What do you do with these savings – none of my business.

Here are the details:

1. _DO_ define similar classes on Java and ActionScript. See details of Java/ActionScript type mapping in the Flex documentation.

2. _DO_ declare these classes as [Bindable] if you envision dynamic updates to the data. Further, _DO_ use collections of these Bindable instances as dataProviders for your DataGrid and let Flex do the miracle: all changes to the data will be reflected by the visual control. There are no miracles, of course: [Bindable] is a shortcut to dispatch event on a data change, the very same event that is expected by ArrayCollection. The collection in turn, dispatches a (different) event on its change. Importantly – the very same event that is expected by the DataGrid.

Let me put it another way: have you ever used collection.itemUpdated()? Well, once you start DTO’s “itemUpdated” will sound to you like the name of the undocumented event :)

OK, I will rub it in further: if you marshall (property) Array of Objects, the Array itself is Bindable, but none of the items are.

3. Make sure that your server-side and client-side DTOs _DO_ provide unique! set/get uuid property. Flex loves this property, do get in love with it too. Flex is using it to identify elements of data presented by the list-based controls. You will find numerous uses for it as well. For instance, instead of sorting by industry, ticker you would sort by industry, ticker and uuid. Why? Because then the hash value will be unique for each record, which would result in substantially better performance.

4. _DO NOT_ hunt for value change on the visual controls (aka View). This task belongs to the data layer (aka Model). Consider replacing [Bindable] public var with the get/set property pair and dispatching the event (PropertyChange) yourself:

private var _amount:Number;
public function get amount() : String{
return _amount;
}
public function set amount( value : Number ):void{
var oldValue:Object = this._amount;
if (oldValue !== value) {
this._amount = value;
dispatchUpdateEvent(“amount”, oldValue, value);
}
}
private function dispatchUpdateEvent(propertyName:String, oldValue:Object, value:Object):void {
dispatchEvent(
PropertyChangeEvent.createUpdateEvent(this, propertyName, oldValue, value)
); �
}

Then, to act on value change, consider customizing the set method. Better yet, consider extending your ActionScript DTO with another class: leave basic layer of DTOs untouched, do customization in the extension. One more gain right here: now you can intercept (breakpoint) whenever your data changes.

5. _DO_ use extension of DTO class (above) to introduce “computed columns”:

public function get unrealizedGain():Number {
return lastPrice – costBasis; �
}

Again, _DO NOT_ use itemEditEnd of the control for these and similar purposes.

_DO NOT_ be afraid of two [RemoteClass] pointing to the same Java DTO: Flex will resolve the reference in favor of the extension layer.

6. Over your project lifespan, you will see many additional fits for DTOs: custom serialization, custom toString() and toXML() methods.

Now, you may say that all these recommendation are way too obvious.

Then I just take off my hat and … see you around Notre-Dame, perhaps.
Otherwise, keep coding.

Victor