Executing a command
• Executing a command appears simple at first, but many details to consider:
– Who creates a command?
– Who invokes a command?
– Who executes a command?
– Who knows the details of the command?
RHS
– SWC 2
Executing a command
• Details to consider (continued):
– When should the command be executed?
– Should the command return a value?
– Should we be able to undo a command?
– What about sets of commands?
RHS
– SWC 3
Executing a command
• Parties involved in a command
– Client : formulates the command
– Invoker : sets the ”wheels in motion” for getting the command executed
– Manager : receives the command from the invoker
– Worker : Actually executes the command
RHS
– SWC 4
Simple commands
• Simple execution of a command:
– Client and Invoker are the same
– Manager and Worker are the same
– Everybody knows all details of the command
– Command executed immediately by Worker
– Command does not return a value
– Command cannot be undone
– Command stands alone
RHS
– SWC 5
Simple commands
Sir, right away, sir!!
Get a shave, now!!
Manager and
Worker
RHS
– SWC
Client and
Invoker
6
Simple commands
• A simple command is similar to a method call
• Not really any reason – or opportunity – for reducing coupling
• For more advanced systems, this is not flexible enough
RHS
– SWC 7
Complex commands
• Consider how an order is processed in a restaurant
– Customer : decides which menu item to order
– Waiter : picks up orders from Customers, and brings them to the Kitchen manager
– Kitchen manager : keeps track of incoming orders, and distributes them to Chefs
– Chef : Prepares the order
RHS
– SWC 8
Complex commands
Chef Customer
Customer
Customer
Customer
Waiter
Kitchen
Manager
RHS
– SWC
Chef
Chef
9
Complex commands
• If the scheme for simple commands was used, customers should yell orders directly to chefs…
• System would break down quickly
• By turning commands into objects, we gain much more flexibility
RHS
– SWC 10
Complex commands
• Using objects for command enables
– Queueing of commands – we can postpone execution of a command
– Undoing of commands
– Logging of commands
– Better separation of knowledge and responsibility – decoupling !
RHS
– SWC 11
Complex commands
• A Customer in a restaurant decides which order to prepare – but does not care about the details of preparation
• The Waiter and Kitchen Manager do not really care about details either
• The Chef, however, must know all details
• Encapsulate what varies…
RHS
– SWC 12
Complex commands
• In OO terms, we therefore need an interface for commands
• Interface for all commands is the same, but implementation is of course specific for each command
Command execute()
RHS
– SWC 13
Contains all details about making pancakes
Complex commands
Command execute()
MakePancakes execute()
MakeSteak execute()
RHS
– SWC 14
Complex commands
• Customer wants pancakes, so he creates a MakePancakes object
• Waiter takes order to Kitchen
Manager, but only knows that it is a Command object (think numbers for an order…)
RHS
– SWC 15
Complex commands
• Kitchen Manager can manage the object (queue it, etc.) but also only knows the interface
• When appropriate, the Kitchen
Manager calls execute on the
Command object
• Code in Command object is then executed (by a Chef)
RHS
– SWC 16
Complex commands
Customer
Command order = new MakePancakes(…);
Waiter manager.send(order);
Kitchen
Manager order.execute();
Chef // Do execute() for MakePancakes
RHS
– SWC 17
The Command pattern
Invoker
Client
Manager
Command
Concrete-
Command
RHS
– SWC
Worker
18
The Command pattern
• The Client can create specific commands
• The Invoker and Manager only knows the
Command interface
• The Worker carries out the actual work defined in the command
• Further flexibility can be introduced by making a Worker interface
RHS
– SWC 19
The Command pattern
Worker action(Command c)
Command setWorker(Worker w) execute()
ConcreteWorker action( Command c )
RHS
– SWC
ConcreteCommand setWorker(Worker w) execute()
20
The Command pattern
// Client code
Worker w = new MergeSortWorker();
Command c = new SortBankAccounts(); c.setWorker(w); theInvoker.invokeCommand(c);
...
// Code from Command public void execute()
{ theWorker.action(this);
}
RHS
– SWC 21
Queueing of commands
• Queueing is used when immediate execution of a command cannot be guaranteed
• Command is executed when needed resources are available
• Queue of command is managed by the
Manager
RHS
– SWC 22
Queueing of commands
• Typical example of a ”producer/consumer” scenario, using threads:
Producer thread h pus
Command
Command
Command
Command
Command
… pop
Consumer
Consumer thread
Thread(s)
RHS
– SWC 23
Undo of commands
• Is – in principle – very easy; just let concrete Command classes implement an undo method, which has the reverse effect of the execute method: public void execute() { light.On(); } public void undo() { light.Off(); }
RHS
– SWC 24
Undo of commands
• Simple or complex command – the specific
Command class always knows how to undo an action.
• Somebody (Manager?) must keep track of which action to undo…
RHS
– SWC 25
Logging of commands
• Primary application is for crash recovery
• Add two new methods Store and Load to the Command interface.
• Store : Save the state of the command to disk
• Load : Load the state on the command into the command. Calling Execute() will now execute the reestablished command.
RHS
– SWC 26
Logging of commands
• Could call Store as part of Execute , or at certain externally defined ”checkpoints”.
• Important use is for transactional processing, where e.g. system crash must not change the execution of the command
Z
Z
Z
RHS
– SWC 27