Codepeek was the very first PureMVC demo, written by me. It has been updated over the years to work with each new version of Apollo then AIR. It is due for a revisit on best practices, though the matter of the Mediator calling the Proxy remains perfectly applicable
1.
The main places where this demo strays is in two places:
1)
The mediators break the encapsulation of the components /**
* The user has initiated a search.
*/
private function beginSearch( event:Event=null ):void
{
codeSearchProxy.search( controlBar.searchTI.text, controlBar.searchCombo.selectedItem );
}
The problem here is that the mediator knows about the children of the controlbar. Instead the controlbar should expose properties that are bound to these values and the Mediator should refer to those properties. This allows the underlying component implementation to change (say from a combo to a list with an appropriate name change) without the affecting the Mediator. It should look like this:
/**
* The user has initiated a search.
*/
private function beginSearch( event:Event=null ):void
{
codeSearchProxy.search( controlBar.searchString, controlBar.selectedLanguage );
}
2)
The Mediator is setting event listeners and registering mediators in its constructor. This should now be done in onRegister:
/**
* Constructor.
*
* <P>
* Populate combo box options and add listeners to
* the viewComponent (the AppControlBar).</P>
*
* @param object the viewComponent (the AppControlBar instance in this case)
*/
public function AppControlBarMediator( viewComponent:Object )
{
super( NAME, viewComponent );
// retrieve and cache a reference to needed proxys
codeSearchProxy = CodeSearchProxy( facade.retrieveProxy( CodeSearchProxy.NAME ) );
// populate combo box on view component
controlBar.comboOptions = codeSearchProxy.searchOptions;
// add listeners to the view component
controlBar.addEventListener( AppControlBar.BEGIN_CODE_SEARCH, beginSearch );
controlBar.addEventListener( AppControlBar.CANCEL_CODE_SEARCH, resetSearch );
controlBar.addEventListener( AppControlBar.CANCEL_CODE_SEARCH, resetSearch );
}
Should look like this:
/**
* Constructor.
*
* <P>
* Populate combo box options and add listeners to
* the viewComponent (the AppControlBar).</P>
*
* @param object the viewComponent (the AppControlBar instance in this case)
*/
public function AppControlBarMediator( viewComponent:AppControlBar )
{
super( NAME, viewComponent );
}
override public function onRegister( )
{
// retrieve and cache a reference to needed proxys
codeSearchProxy = CodeSearchProxy( facade.retrieveProxy( CodeSearchProxy.NAME ) );
// populate combo box on view component
controlBar.comboOptions = codeSearchProxy.searchOptions;
// add listeners to the view component
controlBar.addEventListener( AppControlBar.BEGIN_CODE_SEARCH, beginSearch );
controlBar.addEventListener( AppControlBar.CANCEL_CODE_SEARCH, resetSearch );
controlBar.addEventListener( AppControlBar.CANCEL_CODE_SEARCH, resetSearch );
}
Note that I am also strongly typing the view component, since this Mediator will only ever be used for an AppControlBar. This gives me compile-time checking that ensures I don't try to pass in something else.
And the reason for moving the event listeners and the facade manipulation into the onRegister is based on the assumption that you shouldn't (possibly) be starting conversations you're not prepared to participate in. If you are registered then it is safe to set those event listeners, because whatever system interactions they lead to, you're registered to receive notifications about. Same for fetching proxies and invoking methods on them, sending notifications or registering other mediators. In short defer everything but the call to super until onRegister.
Also, in MultiCore, you
must defer facade manipulation until onRegister, because you don't get your local facade reference until initializeNotifier which is called after the constructor and before onRegister.
I will address these changes in Codepeek. I have over time done my best to cajole authors into refactoring their demos and utilities to suit best practices, but still there are always different styles. Also best practices have evolved over time. Still, for being the oldest PureMVC demo, it's not that far off the rails.
-=Cliff>
1In a typical n-tier system communication has to pass from one tier to the next and can't ever skip over a tier. The MVC triad is an atypical tiered system. It is handy to think of them as tiers because they divide the actors of the system into three distinct groups. But the topology is actually different, more like a triangle than a stack.
If you look at the original MVC pattern (
http://puremvc.tv/#P100/T110) you'll see that it is a valid path for the view to update the model.