Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Applied Java™ Patterns - Stephen Stelting, Olav Maassen.pdf
Скачиваний:
202
Добавлен:
24.05.2014
Размер:
2.84 Mб
Скачать

12.

ObjectInputStream readIn = new ObjectInputStream(new FileInputStream(fileName));

13.

returnValue = readIn.readObject();

14.

readIn.close();

15.

}

16.

else {

17.

System.err.println("Unable to locate the file " + fileName);

18.

}

19.}

20.catch (ClassNotFoundException exc){

21.

exc.printStackTrace();

22.

 

23.}

24.catch (IOException exc){

25.

exc.printStackTrace();

26.

 

27.}

28.return returnValue;

29.}

30.}

Example A.39 RunPattern.java

1.import java.io.File;

2.import java.util.ArrayList;

3.import java.util.Iterator;

4.public class RunPattern{

5.public static void main(String [] arguments){

6.System.out.println("Example for the Chain of Responsibility pattern");

7.System.out.println();

8.System.out.println("This code uses chain of responsibility to obtain");

9.System.out.println(" the owner for a particular ProjectItem, and to");

10.System.out.println(" build up a list of project details. In each case,");

11.System.out.println(" a call to the appropriate getter method, getOwner");

12.System.out.println(" or getDetails, will pass the method call up the");

13.System.out.println(" project tree.");

14.System.out.println("For getOwner, the call will return the first non-null");

15.System.out.println(" owner field encountered. For getDetails, the method");

16.System.out.println(" will build a series of details, stopping when it");

17.System.out.println(" reaches a ProjectItem that is designated as a");

18.System.out.println(" primary task.");

19.System.out.println();

20.

21.System.out.println("Deserializing a test Project for Visitor pattern");

22.System.out.println();

23.if (!(new File("data.ser").exists())){

24. DataCreator.serialize("data.ser");

25.}

26.Project project = (Project)(DataRetriever.deserializeData("data.ser"));

28.System.out.println("Retrieving Owner and details for each item in the Project");

29.System.out.println();

30.getItemInfo(project);

31.}

32.

33.private static void getItemInfo(ProjectItem item){

34.System.out.println("ProjectItem: " + item);

35.System.out.println(" Owner: " + item.getOwner());

36.System.out.println(" Details: " + item.getDetails());

37.System.out.println();

38.if (item.getProjectItems() != null){

39.

Iterator subElements = item.getProjectItems().iterator();

40.

while (subElements.hasNext()){

41.

getItemInfo((ProjectItem)subElements.next());

42.

}

43.}

44.}

45.}

242

Command

In the Personal Information Manager, users might want to update or modify information in their system. This code demonstrates how the Command pattern can provide update and undo behavior for a location.

In this example, a pair of interfaces model the generic command behavior. The basic command action is defined by the execute method in Command, while UndoableCommand extends this interface by adding undo and redo methods.

Example A.40 Command.java

1.public interface Command{

2.public void execute();

3.}

Example A.41 UndoableCommand.java

1.public interface UndoableCommand extends Command{

2.public void undo();

3.public void redo();

4.}

In the PIM, the location of an appointment will be used to implement an undoable command. An appointment stores a description of an event, the people involved, the location, and the start and end time(s).

Example A.42 Appointment.java

1.import java.util.Date;

2.public class Appointment{

3.private String reason;

4.private Contact[] contacts;

5.private Location location;

6.private Date startDate;

7.private Date endDate;

8.

9.public Appointment(String reason, Contact[] contacts, Location location, Date startDate,

Date endDate){

10.this.reason = reason;

11.this.contacts = contacts;

12.this.location = location;

13.this.startDate = startDate;

14.this.endDate = endDate;

15.}

16.

17.public String getReason(){ return reason; }

18.public Contact[] getContacts(){ return contacts; }

19.public Location getLocation(){ return location; }

20.public Date getStartDate(){ return startDate; }

21.public Date getEndDate(){ return endDate; }

22.

23. public void setLocation(Location location){ this.location = location; }

24.

25.public String toString(){

26.

"\n

return "Appointment:" + "\n

Reason: " + reason +

27.

Location: " + location + "\n

Start: " +

28.

 

startDate + "\n

End: " + endDate + "\n";

29.}

30.}

The class ChangeLocationCommand implements the UndoableCommand interface and provides the behavior required to change the location for an appointment.

Example A.43 ChangeLocationCommand.java

1.public class ChangeLocationCommand implements UndoableCommand{

2.private Appointment appointment;

3.private Location oldLocation;

4.private Location newLocation;

5.private LocationEditor editor;

6.

7. public Appointment getAppointment(){ return appointment; }

8.

9.public void setAppointment(Appointment appointment){ this.appointment = appointment; }

10.public void setLocationEditor(LocationEditor locationEditor){ editor = locationEditor; }

243

11.

12.public void execute(){

13.oldLocation = appointment.getLocation();

14.newLocation = editor.getNewLocation();

15.appointment.setLocation(newLocation);

16.}

17.public void undo(){

18.appointment.setLocation(oldLocation);

19.}

20.public void redo(){

21.appointment.setLocation(newLocation);

22.}

23.}

The class provides the ability to change a location using the execute method. It provides undo behavior by storing the previous value of the location and allowing a user to restore that value by calling the undo method. Finally, it supports a redo method that enables users to restore the new location, if they happen to be very indecisive.

Support classes for this example include CommandGui, used to provide a user interface to edit the appointment location.

Example A.44 CommandGui.java

1.import java.awt.Container;

2.import java.awt.event.ActionListener;

3.import java.awt.event.WindowAdapter;

4.import java.awt.event.ActionEvent;

5.import java.awt.event.WindowEvent;

6.import javax.swing.BoxLayout;

7.import javax.swing.JButton;

8.import javax.swing.JComponent;

9.import javax.swing.JFrame;

10.import javax.swing.JLabel;

11.import javax.swing.JPanel;

12.import javax.swing.JTextArea;

13.import javax.swing.JTextField;

14.public class CommandGui implements ActionListener, LocationEditor{

15.private JFrame mainFrame;

16.private JTextArea display;

17.private JTextField updatedLocation;

18.private JButton update, undo, redo, exit;

19.private JPanel controlPanel, displayPanel, editorPanel;

20.private UndoableCommand command;

21.private Appointment appointment;

22.

23.public CommandGui(UndoableCommand newCommand){

24.command = newCommand;

25.}

26.

27.public void setAppointment(Appointment newAppointment){

28.appointment = newAppointment;

29.}

30.

31.public void createGui(){

32.mainFrame = new JFrame("Command Pattern Example");

33.Container content = mainFrame.getContentPane();

34.content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));

36.editorPanel = new JPanel();

37.editorPanel.add(new JLabel("Location"));

38.updatedLocation = new JTextField(20);

39.editorPanel.add(updatedLocation);

40.content.add(editorPanel);

41.

42.displayPanel = new JPanel();

43.display = new JTextArea(10, 40);

44.display.setEditable(false);

45.displayPanel.add(display);

46.content.add(displayPanel);

47.

48.controlPanel = new JPanel();

49.update = new JButton("Update Location");

50.undo = new JButton("Undo Location");

51.redo = new JButton("Redo Location");

52.exit = new JButton("Exit");

53.controlPanel.add(update);

244

54.controlPanel.add(undo);

55.controlPanel.add(redo);

56.controlPanel.add(exit);

57.content.add(controlPanel);

59.update.addActionListener(this);

60.undo.addActionListener(this);

61.redo.addActionListener(this);

62.exit.addActionListener(this);

64.refreshDisplay();

65.mainFrame.addWindowListener(new WindowCloseManager());

66.mainFrame.pack();

67.mainFrame.setVisible(true);

68.}

69.

70.public void actionPerformed(ActionEvent evt){

71.Object originator = evt.getSource();

72.if (originator == update){

73. executeCommand();

74.}

75.if (originator == undo){

76. undoCommand();

77.}

78.if (originator == redo){

79. redoCommand();

80.}

81.else if (originator == exit){

82. exitApplication();

83.}

84.}

86.private class WindowCloseManager extends WindowAdapter{

87.public void windowClosing(WindowEvent evt){

88. exitApplication();

89.}

90.}

92.public Location getNewLocation(){

93.return new LocationImpl(updatedLocation.getText());

94.}

95.

96.private void executeCommand(){

97.command.execute();

98.refreshDisplay();

99.}

100.

101.private void undoCommand(){

102.command.undo();

103.refreshDisplay();

104.}

105.

106.private void redoCommand(){

107.command.redo();

108.refreshDisplay();

109.}

110.

111.private void refreshDisplay(){

112.display.setText(appointment.toString());

113.}

114.

115.private void exitApplication(){

116.System.exit(0);

117.}

118.}

Notice that the CommandGui class implements the interface LocationEditor. This interface defines a method getNewLocation, which provides a way for the ChangeLocationCommand to retrieve the new location from the GUI.

Example A.45 LocationEditor.java

1.public interface LocationEditor{

2.public Location getNewLocation();

3.}

245