Sunday, January 17, 2010

I command you to stop using this pattern - Part 1.

First, a little confession.  I used Cairngorm in version 1.0 of my first Flex application nearly 7 years ago.  By version 2.0, Cairngorm was almost totally ripped out and I have never approached anything close to a rigid application-level MVC framework since.  Now I've had several discussions with my teammates over the years, but lucky for me, I got to make the final decision, so we ultimately ended up building all of our apps with reusable components (similar to the process Yakov Fain promotes.)  I have advocated the Command pattern a couple of times; once for a save button that could show up in multiple places, and once for Undo/Redo functionality on a visual floorplan tool.  I have now learned that the use of this pattern in AS3 is an anti-pattern, but I would argue that our implementations were far purer than what you see out of Flex MVC frameworks today.  I encourage you to read text on the GoF pattern or read the Wiki article on the Command Pattern.  Take note of the very first line in the article, 
"In object-oriented programming, the command pattern is a design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters."
Now think about the Command objects used in PureMVC or Mate.  Their execute functions accept parameters, and they encapsulate nothing.  Now this may be a pattern, and I'm all for putting my own spin on things, but this is in no way a pure implementation of the Command Pattern.  This is just a simple polymorphic utility function.  This accomplishes nothing but separation for separations sake.  It's actually somewhat annoying, and there are so many things wrong with it that I'm thinking about writing a separate post attacking each one.  Some of the things I plan to highlight are


1.  There is no reason for the Command Pattern in a functional language.  Yes, ActionScript 3 is a hybrid functional-OO language and therefore has language constructs that allow you to do this without creating the overhead of an actual pattern.  Quick example:
registerCommand(Constant.COMMAND_NAME, function(notification:INotification):void {

       // do something.
} );
I'm not saying you should do this, I'm only highlighting AS3's ability to eliminate the need to write a state-less class with a single function. 

2.  This impure approach to the command pattern is an attempt to make the design feel like its better engineered. If I was going to use the Command Pattern in AS3, I would encapsulate all the necessary information at the time of construction.  Quick Example:

registerCommand(LOGIN, new LoginCommand(aUser));

with the implementation looking like this
class LoginCommand {
     var _user:User
     public function LoginCommand(user:User):void {

            _user = user;

    }

     public function execute():void {

         _user.login();
/* where user.login() invokes a service call to pass the necessary data to the server.  Curious about who will comment about this.*/
     }
}

Or check out this great example, http://flexscript.wordpress.com/2008/10/17/behavioral-design-patterns-command-design-pattern/


3.  The PureMVC/Mate implementation of this pattern decouples views from business logic (a good thing), but does not reduce the overall decoupling of objects within the application.  Actually, it increases coupling in other places in order to offer the decoupled views.  Quick thought:  how is sendNotification(COMMAND_NAME, params) any different than new Command().execute(params)?

Actually, I wrote this line, and then read Cliff Hall's response to a different question here.  IMO he's advocating the coupling of PureMVC mediators to anything because he sees them as Application specific and not necessarily reusable.  I'll buy that and his comments open my eyes to the problem that PureMVC aims to solve.  BTW.  It's not making your Flex application simpler, smaller, or easier to accept changing requirements.

4. The use of polymorphism to keep the code clean makes more than perfect sense.  I guess there's a line of code somewhere (maybe notifyObservers()) that looks like this:
new commands[notification.getName()]().execute(params)); 
The creation of this convenience mechanism is built in order to not constantly repeat the following:
new MyCommand().execute(new Notification(NAME, params));
 but hiding that level of boilerplate is just sweeping some dirt under a carpet.  It should have been as simple as utils.execute(params), since at this point in the code you know A) what you want to happen next and B) what data you want it to happen on.  The rest is simply fluff AND goes along with my statement about Command Pattern impurity because it's not being created to be called at a later time.

The only way this makes sense is if you actually don't know what Notification you want sent.  If inside a mediator I somehow received a notification, but wasn't sure what it was then I could simply pass that on and the correct command would be called.  But from what I am reading Mediators know...and they are supposed to know what they want to happen.

Now, the purpose of this post was not to attack PureMVC or Mate, it was to attack the my belief that they misuse the Command Pattern and are proliferating that misuse across the Flex Community.  I want everyone to know that it is unneeded in AS3, or any functional language for that matter.  Next post, I will show more realistic examples of the way the Command "non"-Pattern should be used.

Keep in mind, PureMVC's goal is to get as much reuse out of the model as possible.  Many companies provide data and want to provide it across multiple platforms.  I come from a background where we had multiple Flex projects all with totally separate databases for separate customers.  I wanted to reuse my components across those projects, and that has led to my design decisions.  Personally I believe there's a world where both can happen.