It’s great to see more and more enterprise Flex applications being built. However, as the scale and complexity of these applications increase so the design challenges we face.
One problem area is the presentation layer where a plethora of design patterns exist. Paul Williams produced a good series of “blog”:http://blogs.adobe.com/paulw/archives/2007/10/presentation_pa.html posts on presentation models and there is a good “document”:http://www.martinhunter.co.nz/articles/MVPC.pdf from Martin Hunter on MVC, MVP and MVPC. Even with these patterns we still face design challenges if we want to write clean code that is easy to read and stands up to change.
One challenge is messaging between view components. I have seen various solutions and nearly all are based on events. Lets diverge for a bit. Events are a core part of the Flash/Flex programming model and they rightfully have their place, but on the other-hand they are a menace to clean code. As apps scale I have seen too much code polluted with event handling, which obstructs readability. The big problem is the execution path, when the event is fired where does it go? Who is handling it? As the app continues to grow it becomes easier and easier to simply listen for events, the result is we rapidly loose our mental picture of how the code is executing. We often justify this as loose coupling, which I would argue against. I am a proponent of loose coupling, but I want to be able to look at the code and read through the execution path. Tooling is making it easier, but it doesn’t change the fact that the code is no longer readable.
Coming back round to presentation patterns, the other problem I see is an overuse of patterns. Especially within the presentation layer. It seems to be more and more common to combine presentation patterns, giving each their own subtle responsibility. Not only does it detract from the readability but it also confuses new engineers to the project. How do you explain their subtle responsibilities? If you can’t clearly articulate your vision then the design will soon erode and you will be left with a rotten codebase, which is difficult to maintain and extend.
Now I don’t see a silver bullet to these problems, but I would like to suggest an alternative. This emerged from a Pair Programming session with one of my colleagues, Dan Harfleet, who deserves the credit for this approach. We were using the Presentation Model pattern to separate the graphics aspect of the view from its behavior and state. We were using a Panel, which was composed of a couple of view components, each with their own Presentation Model. The main Presentation Model for the Panel was responsible for updating the Panel’s status, but we wanted the nested components to also update the status. How do the Presentation Models communicate?
We wanted to avoid dispatching events and we wanted to avoid using a mediator for the reasons given above. We decided to take a simpler approach, which is based on the Observer pattern. Although it increases coupling, it introduces an explicit contract and allows us to easily read the code execution.
We started by creating two interfaces:
public interface StatusReceiver
function setStatus( message : String ) : void;
public interface StatusNotifier
function addReceiver( receiver : StatusReceiver ) : void;
The main Presentation Model implemented StatusReceiver and all other Presentation Models implemented the StatusNotifier. The attached sample application, which is over simplified, is using "Parsley":http://www.spicefactory.org. All Presentation Models are declared on the Parsley container. On the concrete implementation of StatusNotifier we decorate addReceiver() with the [Inject] metadata tag and Parsley injects the StatusReceiver.
I found this to be a simple solution. The two interfaces form a clear and concise contract and without using events I can easily read the code and understand what is happening.
Downland the sample "here":http://blogs.adobe.com/pmartin/code/PresentationPatternBlog.zip and give it a try. I would interested to here your thoughts.