Design Patterns: Elements of Reusable Object-Oriented Software
74
Command Class and Subclasses
First we define a
Command
abstract class toprovide an interface for issuing a
request. The basic interfaceconsists of a single abstract operation called
"Execute." Subclassesof Command implement Execute in different ways to fulfill
differentrequests. Some subclasses may delegate part or all of the work toother
objects. Other subclasses may be in a position to
fulfillthe request entirely
on their own (see Figure 2.11).To the requester, however, a
Command object is
a Command object
—
theyare treated uniformly.
Figure 2.11: Partial Command class hierarchy
Now MenuItem can store a Command object that encapsulates arequest (Figure 2.12).
We give each menu item objectan instance of the Command subclass that's suitable
for that menuitem, just as we specify the text to appear in the menu item. Whena
user chooses a particular menu item, the MenuItem simply callsExecute on its
Command object to carry out the request. Note thatbuttons and other widgets can
use commands in the same way menuitems do.
Design Patterns: Elements of Reusable Object-Oriented Software
75
Figure 2.12: MenuItem-Command relationship
Undoability
Undo/redo is an important capability in interactive applications. Toundo and redo
commands, we add an Unexecute operation to Command'sinterface. Unexecute reverses
the effects of a preceding Executeoperation using whatever undo information
Execute stored. In the caseof a FontCommand, for example, the Execute operation
would store therange of text affected by the font change along with the
originalfont(s). FontCommand's Unexecute operation would restore the range oftext
to its original font(s).
Sometimes undoability must be determined at run-time. A request tochange the font
of a selection does nothing if the text alreadyappears in that font. Suppose the
user selects some text and thenrequests a spurious font change. What should be
the result of asubsequent undo request? Should a meaningless change cause the
undorequest to do something equally meaningless? Probably not. If theuser repeats
the spurious font change several times, he shouldn't haveto perform exactly the
same number of undo operations to get back tothe last meaningful operation. If
the net effect of executing acommand was nothing, then there's no need for a
corresponding undorequest.
So to determine if a command is undoable, we add an abstractReversible operation
to the Command interface. Reversible returns aBoolean value. Subclasses can
redefine this operation to return trueor false based on run-time criteria.
Do'stlaringiz bilan baham: