University of Cincinnati logo and link  
CinJUG: Design Patterns, October 16, 2006
 
 

Behavioral Patterns - Command Pattern

UC ingot

Intent

“Encapsulate a request as an object, letting you parameterize clients with different requests, queue or log requests, and support undoable operations.” (GoF pg. 233)

Motivation

  • Issue requests to objects without knowing anything about the operation being requested or the receiver of the request. Example: buttons on a toolkit, central login redirection, etc..

  • Command pattern turns the request itself into an object.

  • Command class (interface) declares an interface for executing operations.

  • Command object is often provided to the invoker at instantiation.

  • Command pattern decouples the object that invokes the operation from the one that knows to perform it.

  • Can re-use callers of command objects.

  • Can replace command objects dynamically.

  • Can compose commands in to larger ones. MacroCommand: open-ended number of commands.

  • All possible because object that issues request only needs how to issue the request; not how it will be carried out.

Applicability

  • Callbacks.

  • Specify, queue, and execute requests at different times.

  • Support undo with an 'unexecute' method. Store executed commands in a history list.

  • Support logging and recovery.

  • Strucure a system on high leveloperations built on simple operations.

Participants

  • Command: interface for executing an operation (MonthlyCommand)

  • ConcreteCommand: implements Execute (Annuity, Employee, LifeInsurance).

  • Client: Creates concrete command and sets its receiver (Runner)

  • Invoker: Asks command to carry out request (also Runner).

  • Receiver: knows how to perform operations associated with carrying out a request. (Combined with ConcreteCommand in my implementation)

Collaborations

  • Client creates ConcreteCommand and specifies its receiver.

  • Invoker stores the ConcreteCommand.

  • Invoker issues request by calling execute() on the command.

  • ConreteCommand invokes operations on receiver to carry out request.

Consequences

  1. Decouples object that invokes operation from the one that knows how to perform it.

  2. Command objects are first class objects. Can be manipulated and extended like any other object.

  3. Can assemble commands into a composite command. Composite commands are generally an instance of the Composite pattern.

  4. It's easy to add new commands.

Implementation

  • How intelligent should a command be?

  • Supporting undo and redo.

Applied Login Example

  • Say you want to have a login screen that you want to use in many different parts of a program or web page.  What will happen when the user clicks 'Login'?  In traditional programming, you might have a complex if test that tells the program what page or screen to display next.  But the command pattern lets you do something different.
  • You can have the calling screen or page call the login screen and pass it an object that implements an interface.  Let's say this interface has one method, called login().  When the user clicks the login button, this method is called.  What happens next depends upon what is in the login() method of the object that was passed in by the first screen.  Thus, no if tests, and your program is more flexible!
  • If you want to re-use that login screen on a new piece of functionality, you simply write a new object.  You don't have to rewrite the login screen.
  • Say you are writing a travel web site.  If the user enters the site and hits the 'Login' button, an object is passed with a login() implementation that renders the user's home page.  On the other hand, if the user does not log in, but goes to purchase a ticket, the site might prompt the user to login before making a purchase.  This screen would pass an object with a login() implementation that opens the checkout screen.
  Implementation

 Cincinnati Java Users Group
Resource: http://www.patterndepot.com/put/8/Behavioral.html