Applied Design Patterns with Java

Behavioral :: Command (233) {C ch 17}

Intent
Encapsulate a request as an object, to allow parameterizing clients with different requests, to queue or log requests, and to support 'undo' operations.

As Known As
Action, Transaction

Motivation
It may be necessary to issue requests to objects without knowing anything about the operation being requested or the receiver of the request. GUI toolkits include objects like buttons and menus that carry out a request in response to user input. But the toolkit can't implement the request explicitly in the button or menu, because only applications that use the toolkit know what should be done on which object. A toolkit designer has no way of knowing the receiver of the request or the operations that will carry it out.

The
Command pattern lets toolkit objects make requests of unspecified application objects by turning the request itself into an object. This object can be stored and passed around like other objects. The key to this pattern is an abstract Command class, which declares an interface for executing operations. This interface includes an abstract Execute operation. Concrete Command subclasses specify a receiver-action pair by storing the receiver as an instance variable and by implementing Execute to invoke the request. The receiver has the knowledge required to carry out the request.

Menus can be implemented easily with Command objects. Each choice in a Menu is an instance of a MenuItem class. An Application class creates these menus and their menu items along with the rest of the user interface. The Application class also keeps track of Document objects that a user has opened.

The application configures each MenuItem with an instance of a concrete
Command subclass. When the user selects a MenuItem, the MenuItem calls Execute on its command, and Execute carries out the operation. MenuItems don't know which subclass of Command they use. Command subclasses store the receiver of the request and invoke one or more operations on the receiver. PasteCommand supports pasting text from the clipboard into a Document. PasteCommand's receiver is the Document object it is supplied upon instantiation. The Execute operation invokes Paste on the receiving Document.

OpenCommand's Execute operation is different: it prompts the user for a document name, creates a corresponding Document object, adds the document to the receiving application, and opens the document.

A MenuItem may need to execute a sequence of commands, like centering a page at normal size, which could be constructed from a CenterDocumentCommand object and a NormalSizeCommand object. Because it's common to string commands together in this way, define a MacroCommand class to allow a MenuItem to execute an open-ended number of commands. MacroCommand is a concrete Command subclass that simply executes a sequence of Commands. MacroCommand has no explicit receiver, because the commands it sequences define their own receiver.

Notice how the Command pattern decouples the object that invokes the operation from the one having the knowledge to perform it. This gives flexibility in designing a user interface. An application can provide both a menu and a push button interface to a feature just by making the menu and the push button share an instance of the same concrete Command subclass. Commands can be replaced dynamically, which would be useful for implementing context-sensitive menus. This also supports command scripting by composing commands into larger ones. This is possible because the object that issues a request only needs to know how to issue it; it doesn't need to know how the request will be carried out. The underlying feature providing this flexibility is the use of a Delegate, a recurring theme in Design Patterns.

Catalog Behavioral Prev Next