I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 610 posts at DZone. You can read more from them at their website. View Full User Profile

Design Patterns Uncovered: The Command Pattern

04.02.2010
| 41408 views |
  • submit to reddit

Today's pattern is the Command, which allows the requester of a particular action to be decoupled from the object that performs the action. Where the Chain of Responsibility pattern forwarded requests along a chain, the Command pattern forwards the request to a specific module.

Command in the Real World 

One example of the command pattern being executed in the real world is the idea of a table order at a restaurant: the waiter takes the order, which is a command from the customer.This order is then queued for the kitchen staff.  The waiter tells the chef that the a new order has come in, and the chef has enough information to cook the meal.

 

Design Patterns Refcard
For a great overview of the most popular design patterns, DZone's Design Patterns Refcard is the best place to start. 

The Command Pattern

The Command pattern is known as a behavioural pattern, as it's used to manage algorithms, relationships and responsibilities between objects. The definition of Command provided in the original Gang of Four book on Design Patterns states: 

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

So what does this mean in a class diagram? 

Command declares an interface for all commands, providing a simple execute() method which asks the Receiver of the command to carry out an operation. The Receiver has the knowledge of what to do to carry out the request.  The Invoker holds a command and can get the Command to execute a request by calling the execute method. The Client creates ConcreteCommands and sets a Receiver for the command. The ConcreteCommand defines a binding between the action and the receiver. When the Invoker calls execute the ConcreteCommand will run one or more actions on the Receiver.

The following sequence diagram shows the relationship in a clearer way: 

If this all seems a bit confusing right now, hang on for the code example later on in the article.

When Would I Use This Pattern?

The Command Pattern is useful when:

  • A history of requests is needed
  • You need callback functionality
  • Requests need to be handled at variant times or in variant orders
  • The invoker should be decoupled from the object handling the invocation.

You'll see command being used a lot when you need to have multiple undo operations, where a stack of the recently executed commands are maintained. To implement the undo, all you need to do is get the last Command in the stack and execute it's undo() method.

You'll also find Command useful for wizards, progress bars, GUI buttons and menu actions, and other transactional behaviour. 

So How Does It Work In Java?

Let's use a remote control as the example. Our remote is the center of home automation and can control everything. We'll just use a light as an example, that we can switch on or off, but we could add many more commands.

First we'll create our command interface:

//Command
public interface Command
{
public void execute();
}


Now let's create two concrete commands. One will turn on the lights, another turns off lights:

//Concrete Command
public class LightOnCommand implementsCommand
{
//reference to the light
Light light;

public LightOnCommand(Light light)
{
this.light = light;
}

public void execute()
{
light.switchOn();
}

}

 //Concrete Command
public class LightOffCommand implementsCommand
{
//reference to the light
Light light;

public LightOffCommand(Light light)
{
this.light = light;
}

public void execute()
{
light.switchOff();
}

}


Light is our receiver class, so let's set that up now:

//Receiver
public class Light
{
private boolean on;

public void switchOn()
{
on = true;
}

public void switchOff()
{
on = false;
}

}


Our invoker in this case is the remote control.

//Invoker
public class RemoteControl
{
private Command command;

public void setCommand(Command command)
{
this.command = command;
}


public void pressButton()
{
command.execute();
}

}


Finally we'll set up a client to use the invoker
//Client
public class Client
{
public static void main(String[] args)
{
RemoteControl control = new RemoteControl();

Light light = new Light();

Command lightsOn = new LightsOnCommand(light);
Command lightsOff = new LightsOffCommand(light);

//switch on
control.setCommand(lightsOn);
control.pressButton();

//switch off
control.setCommand(lightsOff);
control.pressButton();

}

}


Watch Out for the Downsides

This pattern ends up forcing a lot of Command classes that will make your design look cluttered - more operations being made possible leads to more command classes. Intelligence required of which Command to use and when leads to possible maintainence issues for the central controller.

Other Articles in This Series
The Observer Pattern
The Adapter Pattern
The Facade Pattern
The Factory Method Pattern
The Abstract Factory Pattern
The Singleton Pattern
The Strategy Pattern The Visitor Pattern
The Decorator Pattern
The Proxy Pattern

Next Up

We're going to look at the Template pattern early next week.

Tags:

Comments

Erik Clairiot replied on Fri, 2010/04/02 - 10:24am

Thanks for this overview.

 ( Receiver implementation may be wrong in switchOff() method)

Mohamed El-beltagy replied on Sun, 2010/04/04 - 12:48am in response to: Erik Clairiot

I think Erik means the Light.swithOff() implementation.. :)

Steven Goldsmith replied on Mon, 2010/04/05 - 10:42am

You can improve on the interface by using generics:


/**
 * Command interface using generic parameters and return values. Implement this
 * using the correct parameter type and return type to have code that handles
 * the command.
 *
 * @param <ParamType> generic parameter type
 * @param <ReturnType> generic return type
*
 * @author sgoldsmith
 */
public interface Command<ParamType, ReturnType> {

    /**
     * Execute command with parameters object and return value after execution.
     *
     * @param params parameters passed
     * @return value returned
     * @throws Exception possible exception
     */
    ReturnType execute(final ParamType params) throws Exception;
}
Then implement :
/**
 * Command to verify SAML signature in Response and return True or False.
*
 * @author sgoldsmith
 */
public class VerifyResponseCommand implements
        Command<SamlCommandParameters, Boolean> {

    /** Logger */
    private static final Logger log = LoggerFactory.getLogger(
            VerifyResponseCommand.class);

    /**
     * Verify SAML signature in Response. Return True if valid signature, False
     * otherwise.
     *
     * @param params SAML command parameters
     * @return True for verified or False if not
     * @throws IOException possible exception
     * @throws MarshallingException possible exception
     * @throws TransformerException possible exception
     * @throws GeneralSecurityException possible exception
     * @throws XMLSignatureException possible exception
     * @throws MarshalException possible exception
     * @throws ParserConfigurationException possible exception
     * @throws ClassNotFoundException possible exception
     * @throws InstantiationException possible exception
     * @throws IllegalAccessException possible exception
     */
    public final Boolean verify(final SamlCommandParameters params) throws
            IOException, MarshallingException, TransformerException,
            GeneralSecurityException, XMLSignatureException, MarshalException,
            ParserConfigurationException, ClassNotFoundException,
            InstantiationException, IllegalAccessException {
        final Document doc =
                SamlCommon.asDOMDocument((Response) params.getXmlObject());
        final Element target = doc.getDocumentElement();
        return SamlSignature.verifySamlSignature(
                SamlCommon.getSignatureFactory(), SamlCommon.getKeyStore(),
                target,params.getAlias());
    }

    /**
     * Execute verify command with SAML parameters object and return True or
     * False depnding on verification.
     *
     * @param params SAML command parameters
     * @return True for verified or False if not
     * @throws Exception possible exception
     */
    @Override
    public final Boolean execute(final SamlCommandParameters params) throws
            Exception {
        return verify(params);
    }
}

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.