THX-1138
THX-1138

Reputation: 21740

Is a link to a receiver is required for proper Command Design Pattern implementation?

Per GoF Design Patterns (wikipedia), ConcreteCommand instance should (must?) have a link (reference) to a Receiver instance. I have following implementation of a command:

internal class PutBlockOntoBlockCommand : ICommand {
    private readonly int _srcTower;
    private readonly int _dstTower;

    public PutBlockOntoBlockCommand(int srcTower, int dstTower) {
        _srcTower = srcTower;
        _dstTower = dstTower;
    }

    public void Execute(Robot robot, Construction construction) {
        robot.MoveBlocks(_srcTower, _dstTower, construction);
    }
}

This co mmand instructs a robot to move blocks on the construction site. Notice that instance of the command has no reference to the instance of the receiver (a Robot); instead the command relies on the Invoker (a RobotCommandCenter in my case) to supply an instance of the Robot to execute the command.

I am convinced that for a command to be a command it shall only encapsulate the intention, and should not be responsible for specifying the target of the command. In my case, as a user, I do not care which robot will be used to execute the job.

So my question is: is it technically valid to refer to the presented implementation as a "Command Design Pattern"?

Upvotes: 0

Views: 57

Answers (1)

tcarvin
tcarvin

Reputation: 10855

First, there are no design pattern police. It's always open to interpretation and colored in shades of gray.

Second, wikipedia is not as good as the original volume, make the investment in the book :)

The GoF list the intent of the Command pattern as:

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

If you meet even one of these intents I'd say you can call it a Command derivative.

You can genrally tell something is a command if it holds the logic for implementing or invoking the desired effect, freeing the holder of the command reference from dealing with these details. Often this is so encapsulated you can do cool things like put them in a list and use the common Execute method defined in the base to perform Redo and Undo very cleanly.

If your base class defined the Execute and your calling code passes all commands the Robot reference then you have a Command, but one with strategy or flyweight aspects that allow you to change the target of the commands. I can see uses for this, though at the cost of things like undo/redo.

Upvotes: 1

Related Questions