Unit 14 Command

67
Unit 14 Command Summary prepared by Kirk Scott 1

description

Unit 14 Command. Summary prepared by Kirk Scott. Design Patterns in Java Chapter 24 Command. Summary prepared by Kirk Scott. The ordinary way for a client to cause a method to execute is to call it, in-line - PowerPoint PPT Presentation

Transcript of Unit 14 Command

Page 1: Unit 14 Command

1

Unit 14Command

Summary prepared by Kirk Scott

Page 2: Unit 14 Command

2

Design Patterns in JavaChapter 24Command

Summary prepared by Kirk Scott

Page 3: Unit 14 Command

3

• The ordinary way for a client to cause a method to execute is to call it, in-line

• There may be other times when the client can’t specify exactly when or where a particular method should be called, but would like to be able to pass the method to another piece of code which will call it when needed

Page 4: Unit 14 Command

4

• This can be accomplished by writing a class which contains the desired method

• Then at run time an instance of that class can be constructed

• That object can have the method called on it• Passing the method can be accomplished by

passing the object to another piece of code as an explicit parameter

Page 5: Unit 14 Command

5

• Book definition:• The intent of the Command pattern is to

encapsulate a request in an object.

Page 6: Unit 14 Command

6

A Classic Example: Menu Commands

• It turns out that menus and listeners work together using the Command design pattern

• In schematic form, these are the steps in creating a menu in code:

• JMenuBar myMenuBar = new JMenuBar();• JMenu myMenu = new JMenu(“File”);• myMenuBar.add(myMenu);

Page 7: Unit 14 Command

7

• These steps are followed by the steps for adding items to the menu:

• JMenuItem myExitMenuItem = new JMenuItem(“Exit”);• ExitListener myExitListener = new ExitListener();• myExitMenuItem.addActionListener(myExitListener);• myMenu.add(myExitMenuItem);

Page 8: Unit 14 Command

8

• The ExitListener is implemented as an inner class of the frame which has the menu

• This is what its code looks like:

• private class ExitListener implements ActionListener• {• public void actionPerformed(ActionEvent event)• {• System.exit(0);• }• }

Page 9: Unit 14 Command

9

• The ExitListener class has an actionPerformed() method in it

• It is the actionPerformed() method that is executed when the Exit item is clicked in the menu

• In the constructor for the frame, where the menu is being created, it is impossible to predict when the Exit item will be clicked

• It is impossible to predict when it will be necessary for the actionPerformed() method to be executed

Page 10: Unit 14 Command

10

• That’s all right• The following line of code shows how

actionPerformed() is linked to the menu item• It is this line of code that illustrates the

Command design pattern• myExitMenuItem.addActionListener(myExitListener);

• The object myExitListener is passed to myExitItem as an explicit parameter in the call to addActionListener

Page 11: Unit 14 Command

11

• The actionPerformed() method can be called on myExitItem in the future in response to a mouse click on myExitItem

• This is mildly cryptic because programmer written code does not contain the call myExitListener.actionPerformed()

• The actual call is made by the system through Java’s event handling mechanism

• Even so, the Command design pattern is evident in the way the item and the listener are linked

Page 12: Unit 14 Command

12

• The book notes that once again, polymorphism is at work in the way menus function

• Each menu item can have a different listener which takes different actions

• Each listener has a method with the same name, actionPerformed()

Page 13: Unit 14 Command

13

• Which action is performed depends on which kind of listener the system calls actionPerformed() on

• The system only needs to know that in each case actionPerformed() should be called, and polymorphism makes sure that the right action is taken for each different kind of listener

Page 14: Unit 14 Command

14

• Challenge 24.1• The mechanics of Java menus make it easy to

apply the Command pattern but 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?

Page 15: Unit 14 Command

15

• Comment mode on:• This may be an interesting question, but the

authors are spinning out into space now• This question is unrelated to understanding

the design pattern in question.

Page 16: Unit 14 Command

16

• Solution 24.1• Many Java Swing applications 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.

Page 17: Unit 14 Command

17

• Notice that the approach just described would be a mess to implement for menus

• If you had a single listener for all menu items, the contents of the actionPerformed() method would degenerate into a series of if/else statements

• These if/elses would have to determine which item had been clicked

• Their bodies would consist of blocks of code implementing the appropriate actions

Page 18: Unit 14 Command

18

• If you think back to the previous chapter, on the Strategy design pattern, that was the kind of mess you were hoping to avoid

• The solution was to have different classes for each strategy (in this case, each menu item)

• Each class would have a method with the same name but containing the implementation of a different strategy (in this case, a different action to be performed)

Page 19: Unit 14 Command

19

• In other words, the handling of menus in Java exhibits the characteristics of two design patterns

• The fact that there are different listener classes, each with an actionPerformed() method illustrates the Strategy design pattern

• The fact that listeners are added to items so that their actionPerformed() method can be called in the future when needed illustrates the Command design pattern

Page 20: Unit 14 Command

20

• Recall also, that as a result of applying the Strategy design pattern you ended up with lots of little classes, each containing just a single method, and which you only needed one instance of

• The same thing happens with menus• There is a different kind of listener for each menu item• Each listener just contains an implementation of

actionPerformed()• Only one instance of each listener is needed

Page 21: Unit 14 Command

21

• The book observes that this is the kind of situation where anonymous classes can be used

• I still don’t like anonymous classes, but it is important to get used to them because other programmers use them

Page 22: Unit 14 Command

22

• The book next presents code with the anonymous listeners missing

• It is not reproduced here because it is immediately followed by a challenge to fill in the missing listeners

• It’s easier to just go directly to the complete example with all of the pieces included

Page 23: Unit 14 Command

23

• Challenge 24.1• Fill in the code for the anonymous subclasses

of ActionListener, overriding the actionPerformed() method. Note that this method expects an ActionEvent argument.

Page 24: Unit 14 Command

24

• Solution 24.2• Your code should look something like this:• Comment mode on:• In the book, the solution code is followed by

some additional remarks• Instead of putting them at the end, they are

given up front here, followed by a comment on them, followed by the code

Page 25: Unit 14 Command

25

• Book’s remarks on the solution code:• Although the actionPerformed() method

requires an ActionEvent argument, you can safely ignore it. The menus() method registers a single instance of an anonymous class with the Save menu item and a single instance of another anonymous class with the Load menu item. When these methods are called, there is no doubt about the source of the event.

Page 26: Unit 14 Command

26

• Comment mode on:• There are two things to say about this:• First of all, the book’s statement forewarns us

that the creation of the menu in the solution code occurs in a separate method in the application, named menus()

Page 27: Unit 14 Command

27

• Secondly, there is nothing new in the remarks about the ActionEvent parameter

• We have always ignored it when writing menu listeners• We’ve seen examples in CS 202 where the event

parameter is of interest• For example, it was necessary to get the (x, y)

coordinates of a mouse click to see if it occurred in a cup

• But quite often, there has been no need to do anything with the event parameter in a listener

Page 28: Unit 14 Command

28

• The book’s solution code is given on the following overheads

• Keep in mind the purpose of the challenge and the code shown

• It is to illustrate how menu listeners (in this case, anonymous ones) make use of the Command design pattern

Page 29: Unit 14 Command

29

• public class Visualization2 extends Visualization {• public static void main(String[] args) • {• Visualization2 panel = new Visualization2(UI.NORMAL);• JFrame frame = SwingFacade.launch(panel, "Operational Model");• frame.setJMenuBar(panel.menus());• frame.setVisible(true);• }

• public Visualization2(UI ui) • {• super(ui);• }

Page 30: Unit 14 Command

30

• public JMenuBar menus() • {• JMenuBar menuBar = new JMenuBar();

• JMenu menu = new JMenu("File");• menuBar.add(menu);

• JMenuItem menuItem = new JMenuItem("Save As...");• menuItem.addActionListener(new ActionListener() • {• public void actionPerformed(ActionEvent e) • {• save();• }• });• menu.add(menuItem);

• menuItem = new JMenuItem("Restore From...");• menuItem.addActionListener(new ActionListener() • {• public void actionPerformed(ActionEvent e) • {• restore();• }• });• menu.add(menuItem);

• return menuBar;• }

Page 31: Unit 14 Command

31

• public void save() • {• try • {• mediator.save(this);• } • catch (Exception ex) • {• System.out.println("Failed save: " + ex.getMessage());• }• }

• public void restore() • {• try • {• mediator.restore(this);• } • catch (Exception ex) • {• System.out.println("Failed restore: " + ex.getMessage());• }• }• }

Page 32: Unit 14 Command

32

Using Command to Supply a Service

• In the previous example, half the work was done by the Java API

• All that was necessary was to plug a command into an existing context

• In other words, the addActionListener machinery is provided by the API

• It is also possible for a programmer to provide both the context and the command

Page 33: Unit 14 Command

33

• The book develops an example where the purpose is to time how long it takes to execute method A

• The idea is that there will be another method, method B, that takes an object as its input parameter which can have method A called on it

• Inside method B there will be timing machinery, the call to method A on the input object, and more timing machinery

Page 34: Unit 14 Command

34

• Let there be an abstract class named Command which includes this abstract method declaration:

• public abstract void execute();• Then a concrete command class would extend

Command and implement execute()• The abstract method, execute(), defines the

interface for using a command object

Page 35: Unit 14 Command

35

• In addition to a concrete command class, the example includes a class named CommandTimer

• This class contains a method named time()• The time() method takes as an input parameter

an instance of a command class• This means that in the body of the time()

method it’s possible to call execute() on that command class object

Page 36: Unit 14 Command

36

• Calls to methods that make it possible to keep track of the passage of time can be placed before and after the call to execute() in the time() method

• Code for the CommandTimer class and its time() method are given on the next overhead

Page 37: Unit 14 Command

37

• public class CommandTimer• {• public static long time(Command command)• {• long t1 = System.currentTimeMillis();• command.execute();• long t2 = System.currentTimeMillis();• return t2 – t1;• }• }

Page 38: Unit 14 Command

38

• The book next presents code to test the setup, with the call that causes the execution missing

• The code with the missing step is not reproduced here because it is immediately followed by a challenge to fill in the missing line of code

• It’s easier to just go directly to the complete example with all of the pieces included

Page 39: Unit 14 Command

39

• It is worth noting that in the example the authors are trying to illustrate the use of a JUnit test framework

• This is mentioned in Appendix C, on the source code, and also at various points in the text

• You don’t have to worry about it• It just adds a little stuff at the end of the example

code which you can ignore• They also use the anonymous class syntax when

creating the command

Page 40: Unit 14 Command

40

• Challenge 24.3• Complete the assignment statement that sets

the value for actual in such a way that the doze command is timed.

Page 41: Unit 14 Command

41

• Solution 24.3• The testSleep() method passes the doze

command to the time() utility method.• [See the code on the next overhead.]

Page 42: Unit 14 Command

42

• public class TestCommandTimer extends TestCase • {• public void testSleep() • {• Command doze = new Command() • {• public void execute() • {• try • {• Thread.sleep(2000 + Math.round(10 * Math.random()));• } • catch (InterruptedException ignored) • {• }• }• };

• long actual = CommandTimer.time(doze);

• long expected = 2000;• long delta = 5;• assertTrue("Should be " + expected + " +/- " + delta + " ms", • expected - delta <= actual• && actual <= expected + delta);• }• }

Page 43: Unit 14 Command

43

• The point of the foregoing example code was that it created an object of the Command class named doze

• This object contained an execute() method that caused it to sleep for a random amount of time

• The line of code shown below made use of the command machinery given previously to time how long it takes for doze.execute() to run

• long actual = CommandTimer.time(doze);

Page 44: Unit 14 Command

44

Command Hooks

• This section builds on material that was presented in the chapter on the Template Method

• You may recall that in that chapter I restricted myself to the discussion of sorting as implemented in the Java API

• I did not pursue the other examples• Therefore, it is not possible to pursue this

example in this chapter• You are not responsible for it

Page 45: Unit 14 Command

45

Command in Relation to Other Patterns

• The next chapter is on the Interpreter design pattern

• It has similarities with the Command design pattern which will be explained in that chapter

• The book states that command is also similar to a pattern in which a client knows when an action is required but doesn’t know exactly which operation to call.

Page 46: Unit 14 Command

46

• This may be true, but notice how the foregoing statement differs from the examples in this chapter:

• In the menu example, there was uncertainty about the timing of the call (sometime in the future) but which actionPerformed() method was linked to which item was well defined

• In the timing example there was also no doubt about what to do—just a need to encase a call to it in other predefined blocks of code

Page 47: Unit 14 Command

47

• Challenge 24.5• Which pattern addresses the situation in which a client

knows when to create an object but doesn’t know which class to instantiate?

• Comment mode on:• Notice that the way this challenge is phrased

introduces yet another difference between the thing they’re talking about and the examples they’re giving:

• Now we’re talking about the creation of an object, not the calling of a method

Page 48: Unit 14 Command

48

• Solution 24.5• In Factory Method, a client knows when to create a new

object but not what kind of object to create. Factory Method moves object creation to a method that isolates a client from knowing which class to instantiate. This principle also occurs in Abstract Factory.

• Comment mode on:• There’s no reason to argue about whether one pattern is

similar to another.• After a while, they all begin to look similar…

Page 49: Unit 14 Command

49

• The Command design pattern can be used with other design patterns

• The book gives code showing Command and Mediator being used together in a MVC design for their Visualization program

Page 50: Unit 14 Command

50

• In case you’ve forgotten, most recently Visualization and VisMediator came up in the chapter on the Memento design pattern

• These two classes were part of the machinery for making the graphical application that showed pictures of machines and saved the state of the application at each stage

• It was not very clear what purpose the mediator class served

Page 51: Unit 14 Command

51

• The mediator class is responsible for returning instances of different kinds of listeners, as needed, for the buttons created in the application

• The example code which will be given next shows part of the controller part of an MVC design

• It’s the creation of a graphical button in a visualization• In it, the kind of listener attached to the button is

determined by a call to a mediator object

Page 52: Unit 14 Command

52

• This is the point where the command pattern is evident

• The call mediator.undoAction() is shown on the next overhead

• This call returns a listener type object, which is attached to the button

• This is analogous to attaching a listener to a menu item, as shown previously

Page 53: Unit 14 Command

53

• protected JButton undoButton() • {• if (undoButton == null) • {• undoButton = ui.createButtonCancel();• undoButton.setText("Undo");• undoButton.setEnabled(false);• undoButton.addActionListener(mediator.undoAction());• }• return undoButton;• }

Page 54: Unit 14 Command

54

• The code on the following overheads shows some of the methods that appear in the mediator class, VisMediator

• There will be different listeners for different actions, but which you get depends on which method you call on the mediator

• It constructs and returns them as needed• Note the use of anonymous classes

Page 55: Unit 14 Command

55

• public ActionListener addAction() • {• return new ActionListener() • {• public void actionPerformed(ActionEvent e) • {• VisMediator.this.add(e);• }• };• }• public ActionListener undoAction() • {• return new ActionListener() • {• public void actionPerformed(ActionEvent e) • {• VisMediator.this.undo(e);• }• };• }

Page 56: Unit 14 Command

56

• public MouseListener mouseDownAction() • {• return new MouseAdapter() • {• public void mousePressed(MouseEvent e) • {• VisMediator.this.mouseDown(e);• }

• public void mouseReleased(MouseEvent e) • {• VisMediator.this.mouseUp(e);• }• };• }• public MouseMotionListener mouseMotionAction() • {• return new MouseMotionListener() • {• public void mouseDragged(MouseEvent e) • {• VisMediator.this.mouseMove(e);• }

• public void mouseMoved(MouseEvent e) • {• }• };• }

Page 57: Unit 14 Command

57

• The book summarizes the application of the command pattern in this example with the following observation

• When the listener is added to the button, the command that is being packaged up in the object is actionPerformed()

• However, what’s important is that actionPerformed() wraps a call to add(), undo(), mouseUp(), or mouseMoved(), depending on what kind of listener is being constructed

• These commands are ultimately what is triggered by this use of the Command design pattern

Page 58: Unit 14 Command

58

• Challenge 24.6• Which pattern provides for the storage and restoration

of an object’s state?• Comment mode on:• This is purely a review question• It is relevant to the Command design pattern only in

the sense that the most recent code example, showing a combination of mediator and command, came from code which illustrated the pattern asked for in this question

Page 59: Unit 14 Command

59

• Solution 24.6• The intent of the Memento pattern is to

provide storage and restoration of an object’s state. Typically, you can add a new memento to a stack with each execution of a command, popping and reapplying these mementos when a user needs to undo commands.

Page 60: Unit 14 Command

60

Summary

• The Command design pattern makes it possible to encapsulate a request for service in an object

• In other words, calls to methods can be managed by passing around objects which can receive the calls

• The actual calls can be made at the time needed or when necessary conditions have been met

Page 61: Unit 14 Command

61

• The Command design pattern is illustrated by the way menus are constructed in Java

• The listener for an item is an object which can have the actionPerformed() method called on it

• The listener is passed to the item as an explicit parameter in a method call

• actionPerformed() is actually executed only at the time that the item in the menu is selected

Page 62: Unit 14 Command

62

• The second example illustrated how the Command design pattern can be used to embed a call between blocks of code

• The third example in the book was not pursued, and you are not responsible for it

• That example happened to illustrate that the command pattern can be used to accomplish things that the Template Method design pattern can also be used to accomplish

Page 63: Unit 14 Command

63

• The idea of passing an object as a parameter and then calling methods on the object in the body of the receiving method is very basic

• You have written code that works this way many times without thinking about it or trying to classify it as some sort of pattern

Page 64: Unit 14 Command

64

• It takes on the meaning of a design pattern depending on the context in which it’s used

• In practice, the command pattern doesn’t necessarily appear in isolation

• It may appear in a more complex design in combination with the Mediator, Memento, and other design patterns

Page 65: Unit 14 Command

65

The End

Page 66: Unit 14 Command

66

• The UML diagram on the following overhead has to do with the section of the chapter that wasn’t covered.

• It is included here after the end for future reference in case it’s needed.

Page 67: Unit 14 Command

67