Upload
sheila-nash
View
215
Download
0
Tags:
Embed Size (px)
Citation preview
Command
RHS – SOC 2
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 – SOC 3
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 – SOC 4
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 – SOC 5
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 – SOC 6
Simple commandsGet a shave,
now!!Sir, right
away, sir!!
Client and
Invoker
Manager and
Worker
RHS – SOC 7
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 – SOC 8
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 – SOC 9
Complex commands
Customer
Customer
Customer
Customer
Waiter
KitchenManager
Chef
Chef
Chef
RHS – SOC 10
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 – SOC 11
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 – SOC 12
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 – SOC 13
Complex commands
• In OO terms, we therefore need an interface for commands
• Interface for all commands is the same, but implemen-tation is of course specific for each command
Commandexecute()
RHS – SOC 14
Complex commands
Commandexecute()
MakePancakesexecute()
MakeSteakexecute()
Contains all details about making pancakes
RHS – SOC 15
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 – SOC 16
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 – SOC 17
Complex commands
Customer
Waiter
KitchenManager
Chef
Command order = new MakePancakes(…);
manager.send(order);
order.execute();
// Do execute() for MakePancakes
RHS – SOC 18
The Command pattern
Client
Invoker Manager
Worker
Command
Concrete-Command
RHS – SOC 19
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 – SOC 20
The Command pattern
Workeraction(Command c)
ConcreteWorkeraction(Command c)
CommandsetWorker(Worker w)execute()
ConcreteCommandsetWorker(Worker w)execute()
RHS – SOC 21
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 – SOC 22
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 – SOC 23
Queueing of commands
• Typical example of a ”producer/consumer” scenario, using threads:
Command
Command
Command
Command
Command
…
Producer
thread
Consumer
thread Consumer
thread Consumer
Thread(s)
push pop
RHS – SOC 24
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 – SOC 25
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 – SOC 26
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 – SOC 27
Logging of commands
• Could call Store as part of Execute, or at certain externally defined ”checkpoints”.
• Important use is for transactional proces-sing, where e.g. system crash must not change the execution of the command
ZZ
Z
RHS – SOC 28
Exercises• Download the NetBeans project CommandExample from the Website (go to Classes,
Week 43)• Examine the code; the project contains many classes, but they do contain comments,
so examine each class in turn• The general idea is to define a DinnerOrder interface, which has the role of a
Command. A couple of implementations of the interface are provided as well; Omelet and Steak
• A DinnerOrder is generated by a Customer, who hands it to a Waitress. The Waitress hands the DinnerOrder to a KitchenManager, who stores the DinnerOrder object in a queue
• When a DinnerOrder is processed, the KitchenManager assigns a Worker to the order. Worker is an interface, which has two concrete implementations; FrenchChef and ItalianChef
• A test is provided in Main. Try it out! Also try to experiment with adding more order and/or worker implementations. Note that only Customer and Worker classes need to know about concrete orders.