Doug Jeffries CS490 Design Patterns May 1, 2003 Command Doug Jeffries CS490 Design Patterns May 1, 2003
Overview What is Command? UML for Command interface Examples Challenge problems
What is Command? GOF definition Object-oriented version of callbacks Encapsulate commands in objects so that you can control their selection, sequencing, queue them, undo them and otherwise manipulate them. Object-oriented version of callbacks Callbacks are functions registered to be called later
What is Command? Keeps the invoker of a function from needing a reference to the receiver which implements the action. Invoker often does not care Simply wants to issue abstract command Sometimes called Transaction or Action
UML
Example Restaurant Customer is the Invoker Waiter is the Command Taking the order is the execution of command Staff are the Receiver Cook prepares the ordered dish Janitor cleans floor after cook spills your food on the floor Waiter delivers it, and probably your bill Paying your bill is another command you will execute Cashier accepts payment Busboy clears the table when you finish Valet brings your car around
In the Wild Where have you seen this pattern?
In the Wild Waiter example javax.swing.Action JButton may be the Invoker no knowledge of Receiver Action is the Command provides actionPerformed() Action delegates to some Receiver
Vehicle Example
Metsker’s Challenge 24.1 The mechanics of Java menus make it easy to apply the COMMAND pattern, but they do not require that you organize your code as commands. In fact, it is common to develop an application in which a single object listens to all the events in a GUI. What pattern does that follow?
Metsker’s Solution 24.1 Java Swing applications commonly apply the MEDIATOR pattern, registering a single object to receive all GUI events. This object mediates the interaction of the components and translates user input into commands for business domain objects.
Metsker’s Challenge 24.2 Fill in the code for the anonymous subclasses of ActionListener, overriding actionPerformed(), noting that this method expects an ActionEvent argument.
Metsker’s Challenge 24.2 protected JMenu fileMenu() { if(fileMenu == null) { fileMenu = new JMenu("File"); Font f = SwingFacade.getStandardFont(); fileMenu.setFont(f); JMenuItem save = new JMenuItem("Save"); save.setFont(f); fileMenu.add(save); save.addActionListener(new ActionListener() { /* CHALLENGE! */ }); JMenuItem load = new JMenuItem("Load"); load.setFont(f); fileMenu.add(load); load.addActionListener(new ActionListener() } return fileMenu;
Metsker’s Solution 24.2 load.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) save(); // or load(); } });
Challenge 1 Compare Command to Strategy
Solution 1 Similarities Differences Both provide ways for actions to be performed abstractly, without having to care about the details of the implementer. Differences Strategy requires the invoker of the action to have a reference to the implementer
Challenge 2 How might Command make it easier to support an undo operation?
Solution 2 Your Command interface could be extended to have an unexecute() method, and state could be stored by the command object itself. Store previously executed commands in a history stack.
Challenge 3 Could logging functionality be added in a similar way as undo was in the previous challenge?
Solution 3 Yes. Simply add load() and save() to the Command interface. State can be restored by reloading the logged commands and executing them in the proper order.
Comments?