↓ Archives ↓

commanding dawn

Over the last few weeks I have been trying to improve the documentation for Dawn on its GitHub page. I am slowly making progress (hindered a little by starting a new job) but realise there are still some real weak spots. One area in particular is Dawn’s use of the command pattern. I built Dawn’s commands in a bit of a rush while completing the project that demonstrated the need for them, so have held back giving them too much formal documentation until I can clean them up and add a couple more key features. That said, I still find them very useful in their current state so thought I’d write this little post to give them more of an airing.

There are lots of good reasons for using commands in your applications. They are a proven solutuion for all sorts of common problems in client side development such as queueing, cacheing, batching etc. They are also very useful for performing business logic that spans multiple domains within an application, and thus belong in no one domain alone.

Why make another command library?

Enough of why commands are good (we all know that), why does Dawn contain its own flavour of this oh so common pattern? In turns out providing the command pattern is not a simple as it might seem in Actionscript, at least not if you have some design principles you intend to stick to. Most of the frameworks I have come accross in actionscript provide commands in a pretty similar way, the steps are somethings like this

  1. Create a new object that implements some ICommand interface
  2. implement the execute method, which takes some generic object as its argument. Find a way to get hold of any objects you need, perhaps a service locator (PureMVC) or a singleton (Caringorm)
  3. define some string or event (a string type field) that triggers the command
  4. configure the framework to trigger the command on the newly defined event (one-to-one mapping)

So what is wrong with that? How could that be better? It seems to me that those steps break a number of principles I think are fairly important, it also looks like a lot of work which could go wrong.

Take step 1. “Create a new object that implements some ICommand interface“. Everyone loves a bit of programming to interfaces! But there a snag here with Actionscript, that ICommand interface will have defined a type for its argument e.g.

interface ICommand{
    function execute(event:FrameworkEvent):void
}

In actionscript there is no way for me to extend an interface and narrow the type of the argument, this for example would be impossible

interface MyCommand extends ICommand{
    function execute(event:MyFrameworkEvent):void
}

What that means is that any commands I write that want to get information out of the event that triggered them are going to have to cast the argument! Type safety FAIL! I want to be able to write type safe commands that know the exact type of their arguments.

Step 2. “implement the execute method, which takes some generic object as its argument. Find a way to get hold of any objects you need, perhaps a service locator (PureMVC) or a singleton (Caringorm)” You can probably guess what I dont like about that. Commands are so valuable because they can encapsulate complex logic that involves a number of parts of an application. But commands are stateless (created each time they are executed) and tend to be created by the framework, so how can they get hold of the objects that they need to act upon? In most frameworks I have come across objects that need to be involved in commands either need to implement the singleton pattern – the enemy of testable code! Or register with a service locator, which adds new dependencies on the command to a service locator class and a random string against which the object may (fingers crossed) be registered against. I want my commands to have as few dependencies as possible, I dont want to have to rely on strings to get hold of the core actors in my system, and I certainly dont want to fall into the many traps thats singletons lay.

step 3. “define some string or event (a string type field) that triggers the command” Having created this command in framework X I now need to think about how to trigger its execution. I might have to create a new object that extends some base event to do this, or I may just have to choose a string name. I can just about deal with this step, I know that there is going to have to be something that triggers the command (I just dont think string or events are very good choices).

step 4. “configure the framework to trigger the command on the newly defined event (one-to-one mapping)” This is where the previous step starts to frustrate me. I have to TELL the framework that the object I just created is the one that will trigger the command. This will most likely look something like so

framework.registerCommand( MyThing.NAME, MyLovelyCommand );

There are a couple of things I don’t like about that, firstly it depends on developer discipline (I dont have that!), meaning it’s up to me to check that the value of MyThing.NAME is what it should be, the compiler won’t care if all my NAME properties have the same value!! Secondly it’s configuration, and configuration does not rock my boat.

how is Dawn different?

Heres an example of what a typical command might look like in Dawn (in a typical hay making application).

class MakeHayCommand{
   [Inject] public var barn:Barn;

   [Execute] public function execute( note:MakeHay ):void{
      barn.makeHay(note.howMuchHay);
   }
}

There are a few things to note

  • there is no ICommand interface
  • the argument to the execute method is specific to the business logic being executed
  • the execute method has [Execute] metadata
  • the barn variable has [Inject] metadata

You might have already guessed that a Dawn command was not going to implement an ICommand interface.  Dawn tries to make the most of Actionscript by using metadata over interfaces here inorder to preserve type safety. When this command is triggered the method that has the [Execute] metadata will be invoked (this also means that we could call the method anything we like, something more meaningful, like, makeTheHay).  Now that we have an argument that is specific to the business logic being executed we no longer need to perform risky runtime casting.

My other major gripe with commands is how core actors within a system are reached, Dawn makes this easy by building upon its dependency injection library.  Just like any other object in Dawn, the command need only specify what it needs by providing the [Inject] metadata.  Dawn will ensure that the relavent objects are constructed/retrieved before the command is executed, so all the logic to fetch domain objects via service locators or singletons is removed, making for a terser more testable command.

While all that type safety would be good on its own it also hands us another easy win with a bit of dry configuration.  We (and Dawn) can see the type of the argument of the execute method, so we can completely skip the configuration step (thats the nasty bit where we start defining strings all over the place), the command is implicitly mapped to the MakeHay notification.

Setting up and triggering a command then looks much simpler

We tell Dawn we have a new command (but skip any mapping step)

commands.addCommand(MayHayCommand);

Since the command system is built on top of Dawns other libraries (DI and notifications) we can just send a notification of type MakeHay to trigger the command.

notificationBus.trigger(new MakeHay(numberOfBales));

and we’re done.

One more quick win

Another nice feature we get for free by building on top of the notification system is that any command you write is mapped by type, and types can be concrete classes (like the above example) or abstract classes or even interfaces.

Here is a command that will log any notification that implements IResponder

class LogRpcCommand {
    [Execute] public function execute( responder:mx.rpc.IResponder ):void {
        trace("making rpc call", responder);
    }
}

Recap

Hopefully I’ve gone someway in justifying why Dawn implements it’s own command pattern.  I wanted to ensure my code stayed type safe, I didn’t want to invent verbose ways of getting hold of objects within the system, and I didn’t want to map classes to string.

I still have someway to go with them, there is more I want from them (queueing baked in etc) but I already find them very useful, and well worth their place in Dawn.

10 Comments

  • [...] This post was mentioned on Twitter by HowDo.us, sammyt123. sammyt123 said: just wrote a blog post on #dawns command pattern http://bit.ly/93kjhJ [...]

  • Jan 18th 201015:01
    by enzuguri

    Reply

    Wow, seems like you’ve put a lot of hard work in here, I checked out the source and am enjoying delving in and out of everything you’ve done.

    I just wondered if you’ve ever taken a look at the parsley framework before?
    http://www.spicefactory.org/parsley/docs/2.1/manual/

    A lot of people are hyping this as the next big thing (especially as it seems to be part of the new caringorm spec), however I initially rejected it because of the heavy footprint for pure as projects.

    Have you any plans to move the framework in this direction at all?

    Thanks again, this looks very promising.

    • Jan 24th 201012:01
      by Sam

      Reply

      Hey enzuguri,
      really glad you are enjoying playing around with Dawn. Let me know if you have any feedback. I have had a look at parsley and it seems like a very solid, impressive framework, as does robotlegs! I’ve not really created Dawn to be the next big thing so am just happy people are finding it useful or fun :)
      Cheers mate, Sam

  • Mar 23rd 201002:03
    by Robert Penner

    Reply

    Why don’t you inject both the barn and note? Then you have a parameterless execute:

    class MakeHayCommand{
    [Inject] public var barn:Barn;
    [Inject] public var note:MakeHay;

    [Execute] public function execute():void{
    barn.makeHay(note.howMuchHay);
    }
    }

    • Mar 23rd 201009:03
      by Sam

      Reply

      hey Robert,

      There are a couple of reason for having the notification as a parameter of the [Execute] method. The most important is that it is used by dawn to automatically map the command class to the notification that triggers it. Adding a command in dawn looks like this

      commandMap.addCommand(MayHayCommand);

      See how I do not have to tell the command map that the MakeHay notification triggers this command! dawn performs reflection on the command, finds the type of the executes parameter and maps (via dawns notification bus) the command to that type. This not only removes a configuration step, it retains the type safety of the command.

      If I was to inject the notification like a dependency of the command, how would dawn know which property to map the command to? (since notifications do not have to implement an interface or extend a type, they are just like any other object).

      I also think it clearly distinguishes between something that is a dependency of the command and a payload that it can work on.

      My other main reason, was that it is felt familiar to most other command patterns I’ve worked with in the past (with the exception of robotlegs?).

      thanks a lot
      Sammy

  • Mar 24th 201002:03
    by Robert Penner

    Reply

    Thanks for the explanation.

    > See how I do not have to tell the command map that the MakeHay notification triggers this command!

    Right, do you mean you’ve avoided doing something like this?

    commandMap.addCommand(MakeHay, MakeHayCommand);

    Basically you’ve moved the MakeHay mapping from one place to another. In order to do that, you defined a new metadata tag, parsed it, and created an inability to use a command interface. Personally, I am reluctant to create new metadata when there’s a simple ActionScript equivalent, which is strongly typed and easier to debug.

    > My other main reason, was that it is felt familiar to most other command patterns I’ve worked with in the past

    When I Google around and look at Wikipedia, I see predominantly execute().

  • Mar 24th 201003:03
    by Robert Penner

    Reply

    I hear what you’re saying about configuration and developer discipline. I would say one of the best enforcers of discipline is the compiler. The Command Map has to be configured somehow, and I would prefer something that will generate a compiler error if configured incorrectly, e.g.:

    commandMap.addCommand(MakeHay, MakeHayCommand);

    Your metadata approach requires its own kind of developer discipline (put a MakeHay parameter in the method and mark with [Execute]). But the compiler doesn’t complain if it isn’t done correctly.

    • Mar 24th 201014:03
      by Sam

      Reply

      Hey, thanks a lot for taking a look at this btw, its awesome to have a critical eye look it over!!

      I totally agree that the compiler is the best tool for spotting errors! Thats my whole aim in increasing type safety.

      The problem I want to avoid (like the plague) is when strongly typed code is in fact not type safe.

      The classic example is events, here is some strongly typed code (the compiler loves it :) ) that is far from type safe

      myObject.addEventListener(Event.Close, function(event:Event):void{});

      // later on

      myObject.addEventListener(MyEvent.Close, function(event:MyEvent):void{});

      Since both MyEvent.CLOSE and Event.CLOSE are equal to “close” both listeners will be triggered by both events, and the strongly typed code will throw a runtime type error.

      So strong typing is very very valuable, but it can also cause unfounded confidence in non-strict code.

      With my approach there is a clear limitation! The developer may misspell Execute, and the compiler will not be there to help them out. But there is also a clear advantage, there is no possibility of the developer triggering a command with an incorrect type that consequently throws a runtime error.

      With the approach of injecting the notification via a property and mapping the command to the notification

      > commandMap.addCommand(MakeHay, MakeHayCommand);

      We remove the problem of the compiler not informing us that the execute method is misspelled, but I do not believe we create a more type safe situation, we just return to adding a mapping step.

      I personally would rather (since there is no silver bullet which achieves type safety and strong typing, that I can yet see) use the approach that keeps the mapping in context, i.e. the mapping is done in the object that takes action on the notification rather than in a removed mapping step.
      It also removes some duplication, since creating a command that depends on a notification via an inject does not definitively map that command to that notifications type, so we then have to map it (two places we have to describe what type the command is expecting). In the approach I am describing the dependency and the mapping are one and the same, so never out of date or in disagreement.

      Phew, that got me thinking

      cheers
      Sammy

  • Mar 24th 201022:03
    by Robert Penner

    Reply

    I’m certainly with you on the event constants. I don’t like mapping with strings, constants or no, because they’re easy to fake. With class and object references, you can’t fake it–you either have the right thing or you don’t.

  • Mar 27th 201005:03
    by Glidias

    Reply

    One thing about the above approach though, you’d have to create a whole list of specific Notification classes to handle each matching command in 1-to-1 mapping (even though they might have the same type of properties and extend from a base class), rather than being able to map 1 notification/event class with multiple string identifiers to be used for each command (1-to-*) in typical RobotLegs fashion. Sometimes, event strings serve as a necessity to conveniently reuse the same event for multiple commands.

    In the 1-to-1 mapping approach, the only way I see how one can lower the number of Notification classes being used (instead of extending meaninglessly to support different Notification class name signatures) is letting the command process some given “type” variable of that notification (via switch-case), and handle multiple command cases tied to a single notification class within the command itself. This could very well mean lesser Command/Event classes being used, but a longer command class code because it handles multiple type cases, moving closer to a 1-shot controller somewhat. It can be a bit harder to manage when dealing with undoable commands which might contain undoable information more specific to a particular action gesture, or more testable commands which should be written as a sole class handling 1 specific case only.

    Another way (for a Robotlegs app i’m doing which handles many commands/gestures) is to simply let each given public static const string in an Event class be marked with some [CommandGesture] meta-data, whose resolved string value must match the given command name (via some logical type-matching convention). When mapping a Command class, the assosiated event/notification class is being inspected for a matching CommandGesture string in the event, and if no matching trigger is found based on the string-matching convention, it throws an error. This does force the developer to create proper events strings that would be resolved to auto-mapped command class names, but at least, the app throws out warnings/errors if the mapping fails. As far as configuration goes, the only thing required is to simply list out all the commands to be auto-wired, since the rest is handled by convention.

  • Leave a Reply