Sunday, April 12, 2009

Implementing the Presentation Model in Flex using daisy-chained ArrayCollections

ArrayCollection is perhaps the most important data type in the Flex framework as it underpins all the data-driven components such as List and DataGrid. One of the things that I don't like about ArrayCollection is that it couples two quite separate concerns, namely data storage and data presentation (i.e. sorting an filtering). In a well architected Flex application storage should be the concern of the data model and presentation should be the concern of the view (or the view's presentation model). If you use ArrayCollection to both store data and to filter and sort the data you have to choose where to put it. The trouble is wherever you choose to put it, it's in the wrong place. Obviously in simple applications this isn't a big deal but in more complex applications getting the separation of concerns right pays big dividends in developer productivity.

Imagine an application that displays streaming market prices. Your user will probably want to be able to filter the prices by product or price (or whatever) and the user may want several different views of the same data in the same application, at the same time. So what do you do? Do you implement this as several ArrayCollections in the data model, one for each view and have your Cairngorm command keep them all up-to-date each time a new price arrives? Obviously there are problems with that approach. Firstly it's a lot of work and secondly every time you add a new view you have to change your command. What that should tell you is that your commands are coupled to you views which is bad news.

Ideally what you want to solve this problem is a single underlying collection in the client-side data model whose concern is data storage and nothing else and several collections in the application's views (or presentation models), whose job is to filter and sort the underlying collection. Using this approach you'd only need to keep one collection synchronized with it's equivalent in the server-side data model (either with polling or with the more elegant LCDS DataService) and the collections in the views (or presentation models) would be filtered and sorted versions of the same underlying collection. When a new price arrives the underlying collection is updated and what you want is that all the dependent collections in the views update accordingly.

This separation of concerns between view-agnostic data in the data model and view-specific versions of the underlying data in the presentation model is the fundamental idea that underpins Martin Fowler's presentation model pattern, a pattern that's already been made popular in the Flex community by Paul Williams, Borre Wessel and David Deraedt

The good news is that it's pretty trivial to implement this sort of separation of concerns in Flex using the ListCollectionView class. ListCollectionView provides the filtering and sorting functionality of an ArrayCollection and its list property allows you to define, what is effectively, a dataProvider allowing you to link them together like a daisy chain. (Had the list property been named dataProvider by Adobe it might be more obvious that this functionality exists but that's another story.)

Anyway here's a simple example that demonstrates how to daisy-chain ListCollectionViews with an ArrayCollection like this. Clearly in a real application the underlying view-agnostic data collection would be in the data model, the view-specific sorted/filtered collections would be in the relevant presentation model and there would be no ActionScript in the view but you get the idea.


Anonymous said...

Great Article , but for us newbies , would it be possible to post the actual break out of the example with its separate files. I get the concept , but would like to see how it 'should' be implemented :) .

Justin J. Moses said...

Nice post Graeme. I hope you keep the blogging up - looks like it's been a while between posts.


Flex developer said...

Great Post Graeme, very well and detailed informations. Thank you for the kind effort looking forward for more posts from you.