Command pattern and AS3

actionscript-3, design-patterns, flash

Solution

The command pattern is all about separating out concerns between three different categories of objects:

- The Invoker

- The Receiver

- The Command

Which, as wvxvw pointed out, usually means that you have a TON of classes that implement `ICommand` that really just work as proxies to call methods on a Receiver -- which is required for Java. This can get a little unmanageable over time.

But lets look at some code, I'm going to follow the sample code that that introduces the basics of the command pattern found here, but simplified slightly for clarity:

So first the receiver:

// Receiver
public interface IStarShip {
    function engage():void;
    function makeItSo():void;
    function selfDestruct():void;
}

public class Enterprise implements IStarShip {
    public function Enterprise() { }

    public function engage():void {
        trace(this, "Engaging");
    }

    public function makeItSo():void {
        trace(this, "Making it so");
    }

    public function selfDestruct():void {
        trace(this, "Self Destructing");
    }
}

And the invoker:

// invoker
public class CaptPicard {
    private var _command:ICommand;

    public function CaptPicard() { }

    public function set command(cmd:ICommand):void {
        this._command = cmd;
    }

    public function issueCommand():void {

    }
}

And finally some commands:

// command
public interface ICommand {
    function execute():void;
}

public class EngageCommand implements ICommand 
{
    private var receiver:IStarShip

    public function EngageCommand(receiver:IStarShip) {
        this.receiver = receiver;
    }

    public function execute():void {
        receiver.engage();
    }
}

public class SelfDestructCommand implements ICommand 
{
    private var receiver:IStarShip

    public function SelfDestructCommand(receiver:IStarShip) {
        this.receiver = receiver;
    }

    public function execute():void {
        receiver.selfDestruct();
    }
}   

public class MakeItSoCommand implements ICommand 
{
    private var receiver:IStarShip

    public function MakeItSoCommand(receiver:IStarShip) {
        this.receiver = receiver;
    }

    public function execute():void {
        receiver.makeItSo();
    }
}   

And we can hook these up by saying something like:

var enterprise:Enterprise = new Enterprise;
var picard:CaptPicard = new CaptPicard();
picard.command = new SelfDestructCommand(enterprise);
picard.issueCommand();

So far, it follows fairly closely with the example code, and is a pretty standard implementation of the Command Pattern in ActionScript. But, right now we have three `ICommand` implementations and as the number of things that a reciever can do increase, so does the number of commands that are required to orchestrate the pattern.

And if we start to examine the Command itself, it doesn't really do much other than tell the receiver to do some work. As wvxvw implied, there is already the facility in actionscript to do just that: First-class function.

Lets take a look at possible implementation of that to reduce the number of implementations of ICommand you need to have floating around, without changing your pattern at all.

Lets say that we made a generic type of command, lets say:

public class GenericCommand implements ICommand {

    private var worker:Function;

    public function GenericCommand(worker:Function) {
        this.worker = worker;
    }

    public function execute():void {
        this.worker.call();
    }
}

Notice that our new type still implements `ICommand`, but instead of being bound directly to some implementation, it accepts a worker to do some work on. It doesn't execute it right away, it just holds on to it and waits for something else to put it in motion.

Then we could switch our code to being something like this:

var enterprise:Enterprise = new Enterprise;
var picard:CaptPicard = new CaptPicard();
picard.command = new GenericCommand(function() { enterprise.selfDestruct(); });
picard.issueCommand();
picard.command = new GenericCommand(function() { enterprise.engage(); });
picard.issueCommand();
picard.command = new GenericCommand(function() { enterprise.makeItSo(); });
picard.issueCommand();

With this one `GenericCommand`, we could unroll all of our commands into this new pattern (or mix and match between them).

But if you look close, you can see by using this we are tightly coupling a generic command to a IStarShip by referencing the closed-over variable `enterprise`, and perhaps even more worrying is if we aren't careful we could be creating a ton of these closures. They would all need to be garbage collected at some point, which could effect performance, or worse cause a memory leak.

We could decouple that one layer more and make it even more dynamic. Rather than using closing over directly to the local variable `enterprise` we could use a factory pattern to help generate our command dynamically on the fly. Consider this:

public class StarShipCommandFactory {
    private var worker:Function;

    public function StarShipCommandFactory(worker:Function) {
        this.worker = worker;
    }

    public function to(receiver:IStarShip):ICommand {
        return new GenericCommand(function() {
            worker.call(undefined, receiver);
        });
    }
}

Then we can use that to create a command factory for creating these commands. Something like:

var enterpriseA:Enterprise = new Enterprise();
var enterpriseB:Enterprise = new Enterprise();
var picard:CaptPicard = new CaptPicard();

var selfDestuctor:StarShipCommandFactory = new StarShipCommandFactory(function(starShip:IStarShip):void {
    starShip.selfDestruct();
} );

var blowUpA:ICommand = selfDestructor.to(enterpriseA);
var blowUpB:ICommand = selfDestructor.to(enterpriseB);

picard.command = blowUpA;
picard.issueCommand();

picard.command = blowUpB;
picard.issueCommand();

This will all reduce the number of static classes that you need to generate in favor of dynamically created objects leveraging the properties first-class functions, but still applying the same general idea.

In fact, with this pattern you can build up very complicated commands that proxy to multiple actions on multiple receivers, which can be a very powerful thing.

Why would you want to use traditional implementations of `ICommand` then?

One of the biggest reasons to stick with the traditional pattern is ease in serialization. Because the objects are explicit, it makes them very easy to serialize. So, lets say you had a stack of `Vector.<ICommand>`. You could easily serialize them, write them out, then later, reload them and replay them in order and should be at the exact same state that you were. Dynamically generated objects like the ones I described before a little more tricky to do that with -- not impossible, just trickier.

If you are concerned about maintaining a huge number of `ICommand`s that map to receiver actions, then in the past I have used meta-programming to solve this problem. Use ruby/python to parse a set number of files, and automatically generate the `ICommand` mappings. They are, a lot of the times, fairly naive implementations, which are prime candidates for automation.

Anyway, those are my thoughts on the subject. There are a lot more things that you could do to help simplify your code -- I have just scratched the surface. Your mileage may vary -- Remember: "Find a pattern that solves your problem, not the other way around" -- but perhaps you can glean some useful information from it.

Problem

Just curious how do you guys solve the problem of encapsulation of commands. Are you creating a separate class for each command? Or there's another way (without huge amount of classes)? Note that I'm facing the problem on action script 3. Upd: to be more precise, I want to know how to organize command related machinery (e.g. class for each command). Thank you in advance!

Original source