|
|
Behavioral Patterns - Command Pattern
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
-
Decouples
object that invokes operation from the one that knows how to perform it.
-
Command
objects are first class objects. Can be manipulated and extended like
any other object.
-
Can
assemble commands into a composite command. Composite commands are
generally an instance of the Composite pattern.
-
It's easy
to add new commands.
Implementation
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

Resource:
http://www.patterndepot.com/put/8/Behavioral.html
|