Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.
-
Upload
claud-walker -
Category
Documents
-
view
214 -
download
0
Transcript of Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.
![Page 1: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/1.jpg)
Linzhang Wang
Dept. of Computer Sci&Tech,
Nanjing University
The Command Pattern
![Page 2: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/2.jpg)
Intent
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
Also Known as Action, Transaction
![Page 3: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/3.jpg)
Motivation(1)
Sometimes it’s necessary to issue requests to objects without knowing anything about the operation being requested or the receiver of the request. Like impl. of buttons, menus in user interface
toolkits. The Command pattern lets toolkit objects make
requests of unspecified application objects by turning the request itself into an object.
![Page 4: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/4.jpg)
Motivation(2)
The key of this pattern is an abstract Command class, which declares an interface for executing operations.
Concrete Command subclasses specify a receiver-action pair by storing the receiver as an instance variable and by implementing Execute to invoke the request.
![Page 5: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/5.jpg)
Motivation(3)
Application creates menus and menuitems.
Application also keep track of Document objects.
Application
Add(Doc)
Menu
Add(MenuItem)
MenuItem
Clicked()
Command
Execute()
Command ->Execute()
Document
Open()Close()Cut()Copy()Paste()
![Page 6: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/6.jpg)
Motivation(4)
PasteCommand supports pasting text from the clipboard into a Document
Command
Execute()
PasteCommand
Execute()
document->Paste()
Document
Open()Close()Cut()Copy()Paste()
![Page 7: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/7.jpg)
Motivation(5)
OpenCommand
Command
Execute()
OpenCommand
Execute()
AskUser()
name=AskUser();doc = new
Document(name)doc->open()
Application
Add(Document)
![Page 8: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/8.jpg)
Motivation(6)
Macro Command to execute a series of commands
Command
Execute()
MacroCommand
Execute()
for all c in commandsc->Execute
![Page 9: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/9.jpg)
Motivation(7)
The Command pattern decouples the object that invokes the operation from the one having the knowledge to perform it.
We can replace commands dynamically. We can also support command scripting by
composing commands into larger ones.
![Page 10: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/10.jpg)
Applicability(1)
Use this pattern when parameterize objects by an action to perform.
Commands are object-oriented replacement for callbacks in procedural language.
specify, queue, and execute requests at different time.
support undo. The Command’s Execute operation can store state for reversing its effects in the command itself.
![Page 11: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/11.jpg)
Applicability(2)
support logging changes so that they can be reapplied in case of a system crash.
structure a system around high-level operations built on primitives operations.
![Page 12: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/12.jpg)
Structure
Client Invoker Command
Execute()
Receiver
ConcreteCommandExecute()
state
Action()
![Page 13: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/13.jpg)
Participants(1)
Command declares an interface for executing an operation.
ConcreteCommand defines a binding between a Receiver object and an
action implements Execute by invoking the corresponding
operation on Receiver.
![Page 14: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/14.jpg)
Participants(2)
Client(Application) creates a ConcreteCommand object and sets its
receiver. Invoker
asks the command to carry out the request. Receiver
knows how to perform the operations associated with carrying out a request. Any class may serve as a Receiver.
![Page 15: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/15.jpg)
Collaborations(1)
The client creates a ConcreteCommand object and specifies its receiver.
An Invoker object stores the ConcreteCommand object. The invoker issues a request by calling Execute on the
command. When commands are undoable, ConcreteCommand stores state for undoing the command prior to invoking Execute.
The ConcreteCommand object invokes operations on its receiver to carry out the request.
![Page 16: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/16.jpg)
Collaborations(2)
sequence diagram
new Command(aReceiver)
Action()
StoreCommand(aCommand)
aReceiver
aClient aCommand
anInvoker
Execute()
![Page 17: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/17.jpg)
Consequence
Command decouples the object that invokes the operation from the one that knows how to perform it.
Commands are first-class objects. They can be manipulated and extended like any other object.
You can assemble commands into a composite command. (MacroCommand).
It’s easy to add new Commands, because you don’t have to change existing classes.
![Page 18: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/18.jpg)
Implementation(1)
How intelligent should a command be? One extreme: merely defines a binding between a
receiver and the actions that carry out the request. Another extreme: it implements everything itself:
useful when want to define commands that are independent of existing
receiver. no suitable receiver exists, or when a command knows its receiver implicitly.
Somewhere between: commands that have enough knowledge to find their receiver dynamically.
![Page 19: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/19.jpg)
Implementation(2)
Supporting undo and redo additional state needed, including: The Receiver object. the arguments to the operation performed on the
receiver, any original values in the receiver that can change
as a result of handling the request.
![Page 20: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/20.jpg)
Implementation(3)
Supporting undo and redo(2) The application needs a history list of commands
that have been executed. An undoable command might have to be copied
before it can be placed on the history list. Commands that must be copied before being placed
on the history list act as prototypes.
![Page 21: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/21.jpg)
Implementation(4)
Avoiding error accumulation in the undo process. Hysteresis can be a problem in ensuring a reliable,
semantics-preserving undo/redo mechanism. Errors can accumulate.
Memento pattern can be applied to give command access to this information without exposing the internals of other objects.
![Page 22: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/22.jpg)
Implementation(5)
Using C++ templates We can use templates to avoiding creating a
Command subclass for every kind of action and receiver for commands that aren’t undoable don’t require arguments
Will be shown in the Sample Code section.
![Page 23: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/23.jpg)
Sample Code(1)
Abstract Command classclass Command {public:
virtual ~Command();virtual void Execute() = 0;
protected:Command();
}
![Page 24: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/24.jpg)
Sample Code(2)
OpenCommand classclass OpenCommand : public Command{public:
OpenCommand(Application *);virtual void Execute();
protected:virtual const char* AskUser();
private:Application* _application;char* _response;
};OpenCommand::OpenCommand(Application *a) {
_application = a;}
![Page 25: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/25.jpg)
Sample Code(3)
OpenCommand(continued)void OpenCommand::Execute(){
const char* name = AskUser();
if ( name != 0) {
Document *document = new Document(name);
_appplication->Add(document);
document->Open();
}
}
![Page 26: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/26.jpg)
Sample Code(4)
PasteCommand classclass PasteCommand : public Command {public:
PasteCommand(Document *);virtual void Execute();
private:Document * _document;
}PasteCommand::PasteCommand(Document* doc) {
_document = doc;}void PasteCommand::Execute() {
_document -> Paste();}
![Page 27: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/27.jpg)
Sample Code(5)
template for simple commandtemplate <class Receiver>
class SimpleCommand : public Command{
public:
typedef void (Receiver::*Action)();
SimpleCommand(Receiver* r, Action a):
_receiver(r), _action(a){}
virtual void Execute();
private:
Action _action;
Receiver* _receiver;
}
![Page 28: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/28.jpg)
Sample Code(6)
template for simple commandtemplate <class Receiver>
void SimpleCommand<Receiver>::Execute(){
(_receiver->*_action)();
}
![Page 29: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/29.jpg)
Sample Code(7)
Using templateMyClass* receiver = new MyClass
…
command* aCommand =
new SimpleCommand<MyClass>
(receiver, &MyClass::Action);
aCommand->Execute();
![Page 30: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/30.jpg)
Sample Code(8)
MacroCommand classclass MacroCommand : public Command {public:
MacroCommand();virtual ~MacroCommand();virtual void Add(Command *);virtual void Remove(Command *);virtual void Execute();
private:List<Command *>* _cmds;
}
![Page 31: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/31.jpg)
Sample Code(9)
Execute MacroCommandvoid MacroCommand::Execute() {
LIstIterator<Command*> i(_cmds);
for(i.First(); !i.IsDone(); i.Next())
{
Command *c = i.CurrentItem();
c->Execute();
}
}
![Page 32: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/32.jpg)
Sample Code(10)
void MacroCommand::Add(Command *c) {
_cmds->Append(c);
}
void MacroCommand::Remove(Command *c)
{
_cmds->Remove(c);
}
![Page 33: Linzhang Wang Dept. of Computer Sci&Tech, Nanjing University The Command Pattern.](https://reader035.fdocuments.us/reader035/viewer/2022070403/56649f2a5503460f94c442d2/html5/thumbnails/33.jpg)
Related Patterns
A Composite can be used to implement MacroCommands.
A Memento can keep state the command requires to undo its effect.
A command that must be copied before being placed on the history list acts as a Prototype.