I have found that using Commands for all my calls makes me feel more comfortable in that I dont have to tie my mediators to certain Proxies when there are changes to them but rather Commands are tied up to Proxy and Mediator Notifications.
This feels more natural forcing me to create my Mediators/Views/Proxies more open and not having references (or importing) from each other but they just expose their APIs which the controls are able to use as needed.
Conceptually, there is nothing wrong with putting all of your application's Model tier interaction into Commands if it 'feels more natural' to you, except that it uses up way more cycles than necessary to get things done.
The Mediator is a long-lived actor, and therefore may establish a collaborative relationship with the Proxies (also long-lived actors) by declaring interest in their notifications and retrieving a local reference to those Proxies at onRegister time. This allows it to respond directly to Proxy notifications and to invoke methods directly on Proxy collaborators without having to retrieve them each time.
A Command, however requires notification from the Mediator (the first additional step), instantiation (second additional step), retrieval of Proxies (third additional step). Since a Command is instantiated only when needed and discarded thereafter, these extra steps must happen every time.
If you consult a diagram of the original MVC meta-pattern1
, you see that the View and Controller are equally permitted to update the Model. They have direct associations. The Model on the other hand may only send notifications to the View. If anything, PureMVC is overly permissive
in it's allowing Commands to be triggered by notifications from the Model.
Keep in mind that the View tier has no other purpose in life than to allow the user to interact with and update the Model. Therefore it is completely acceptable that the Mediator would collaborate with any Proxies necessary to fulfill its use cases. The place in the View tier that you're concerned about remaining portable is the view components themselves. The Mediators perform this decoupling for us, allowing us to write portable view components that know nothing of the PureMVC apparatus to which they are attached.
When we talk about loose-coupling (and the effort expended in to achieve it), it is important to consider which couplings we're most concerned about. If you're feet are tied, but you're neck is in a noose, which coupling is more important to loosen first? If you wear your self out untying your feet, you may collapse on the noose when you're done. But at least you're feet will be unbound, right?
At the MVC level the coupling that you want to concern yourself with most is not
how strongly your View is coupled to your Model, but visa versa. You want to ensure that your Model knows nothing about the rest of your application and keeps itself focused on the domain model.
Unless you are specifically setting out to write a view component that will be resold, (ala ILog Elixir), your greatest potential for reuse is in the Model. Always assume that the web client you write today will have desktop and mobile counterparts later. With the new version of AIR already running on many phones, this potential has never been greater that one Model tier library could be reused in all three applications. The form factors and use cases will probably be quite different in these companion apps.
You might reuse some of the same view components, but the Mediators will likely be unique to the application they're a part of and will not be good targets for reuse. But if you've abstained from letting your Model know anything about the rest of the app, then you can package it separately and use the same library in all your apps.
The other consideration that figures into whether to put Model tier interaction into a Command rather than a Mediator (on a case by case basis, not as an across the board practice) is DRYness. (i.e. Don't Repeat Yourself). When you have the same code in multiple places, then updating it requires visiting more than one actor; a bad maintenance legacy.
So if you have logic that you are triggering both from a button in one view component and from a keystroke grabbed in another, then you have a potential candidate for logic to be moved into a Command so that you can ensure that the same thing happens in both places.
-=Cliff>1 MVC Diagram attached, via Wikipedia