Chapter 19 Memento
description
Transcript of Chapter 19 Memento
![Page 1: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/1.jpg)
1
Chapter 19Memento
Summary prepared by Kirk Scott
![Page 2: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/2.jpg)
2
![Page 3: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/3.jpg)
3
![Page 4: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/4.jpg)
4
![Page 5: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/5.jpg)
5
Design Patterns in JavaChapter 19Memento
Summary prepared by Kirk Scott
![Page 6: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/6.jpg)
6
The Introduction Before the Introduction
• This is a succinct preview summary of the memento examples:
• 1. You can save the state of a running application in a stack data structure
• 2. You can also save the state of an application in secondary storage using serializability
![Page 7: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/7.jpg)
7
• It’s worth noting again that there is some utility in the authors’ emphasis on intent
• Structurally, there is no close relationship between a stack and serializability
• However, in their respective contexts, transient vs. persistent storage, they can both be used in order to accomplish the same thing
![Page 8: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/8.jpg)
8
• The book’s examples are based on adding an undo feature to the graphic visualization of a factory
• Whenever a change is to be made to the state of the visualization, a copy of the current state is saved before the change is made
• When the undo option is selected, the current state is replaced by the most recently saved state
![Page 9: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/9.jpg)
9
• Book definition:• The intent of the Memento pattern is to
provide storage and restoration of an object’s state
![Page 10: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/10.jpg)
10
A Classic Example: Using Memento for Undo
• A memento may be as simple as a single object that holds an application’s state
• It may also turn out that some collection of objects or some data structure (like a stack) is involved in implementing the memento pattern
![Page 11: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/11.jpg)
11
• From a practical point of view, these kinds of questions have to be answered:
• How will state be captured in a memento?• When will the state be captured?• How will the previous state be restored based
on the contents of the memento?
![Page 12: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/12.jpg)
12
• On the next overhead the graphical visualization of a factory is shown at software start-up
• Its state is currently empty—but it’s important to note that empty is a state
• Since nothing has been done yet, the Undo button is disabled
![Page 13: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/13.jpg)
13
![Page 14: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/14.jpg)
14
• The next overhead shows the application after a few machines have been added and dragged around the work area
• Note that the Undo button is no longer disabled
![Page 15: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/15.jpg)
15
![Page 16: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/16.jpg)
16
• The scenario under discussion is one of run-time functionality
• The state that needs to be captured is a list of the locations of the machines that the user has placed in the application
• One such list is a memento• A history of multiple states is stored in a stack• Clicking the Undo button means popping the
stack
![Page 17: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/17.jpg)
17
• In particular, the book outlines the functionality in this way:
• 1. Each time the user takes an action like add or move, a memento will be created and pushed onto the stack
• 2. Each time the user clicks Undo, the stack will be popped, removing the current state, and the state will be restored to the previous state, which is now at the top of the stack
![Page 18: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/18.jpg)
18
• At start-up time, a memento of the empty state will be pushed onto the stack
• The visualization always has a state and the stack will never be empty
• The Undo button will be disabled when the stack only has a single entry in it
• It will not be possible to pop the empty state off of the stack
![Page 19: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/19.jpg)
19
• Comment mode on:• The book hasn’t stated how the list of
machine locations will be saved yet, but strictly speaking, such a list is the literal memento in the application
• The stack is used in order to manage a collection of potentially more than one memento
![Page 20: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/20.jpg)
20
• Comment mode, continued:• The book’s approach may not be elegant, but
it’s straightforward• Notice that they aren’t trying to save a list of
actions, for example• This means that it’s not necessary to figure
out how to undo an action
![Page 21: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/21.jpg)
21
• Comment mode, continued:• Instead, complete states are saved• Then undoing simply means restoring the
previous state• I would note that there seems to be a lot of
redundancy in storing all of the previous states in this way
![Page 22: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/22.jpg)
22
• I suspect that it would be possible to model state as a sequential collection of machines and a sequence of actions taken on them
• This might result in less redundancy among the mementos
• The code for undoing would be considerably more complex than simply restoring the list of previous machine locations
![Page 23: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/23.jpg)
23
What the Book Does Next
• In keeping with the plan of previous chapters, the book develops the application step-by-step
• It gives an initial solution• It then modifies that solution• The solutions illustrate a particular coding
technique which isn’t part of the pattern but which deserves explanation
![Page 24: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/24.jpg)
24
• In general, this is what should happen when the user interacts with the visualization:
• When a machine is added or moved, the factory model should change accordingly,
• The appearance of the visualization should be updated,
• The state should be saved
![Page 25: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/25.jpg)
25
• When the user clicks Undo the previous state should be restored to the model
• The appearance of the visualization should also be updated when this happens
• The application reacts to events by means of a mouse listener in the work area and listeners for the Add and Undo buttons
![Page 26: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/26.jpg)
26
• Notice how this problem description seems like it might be ripe for an MVC solution
• In its solutions the book doesn’t use listener and observer like in full MVC
• However, it does use listening in order to achieve its goal
• (You could argue whether the implementation is “MVC in spirit”—which may be a dangerous oxymoron.)
![Page 27: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/27.jpg)
27
The Book’s First Solution
• On the next overhead, a UML diagram of the FactoryModel class is shown with references to instances of the system supplied Stack and ArrayList classes
• The stack holds the mementos• The instance of ArrayList holds the listeners for
the graphical components of the application• This second point will merit discussion
![Page 28: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/28.jpg)
28
![Page 29: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/29.jpg)
29
The Book’s Coding Technique Applied to this Problem
• Ultimately, it’s the stack of mementos that is of real interest
• However, there is no escaping the ArrayList of listeners in the design
• Notice that the FactoryModel class also implements methods named addChangeListener() and notifyListeners()
![Page 30: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/30.jpg)
30
• It is neither inherently good or bad to gather listeners together in an ArrayList
• We’re seeing something of how listeners are managed in system supplied classes only in programmer written code
• From the perspective of the previous unit, the important point is that we have a GUI, but we are not using the Observer design pattern in order to an MVC application
![Page 31: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/31.jpg)
31
• The diagram hasn’t broken out the view yet• But from this initial diagram alone, it is
apparent that the model and the controller functionality are intertwined
• You might say the authors have implemented an “MVC design in spirit”, although that might be an oxymoron
![Page 32: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/32.jpg)
32
• In any case, the first task is to be clear about how the ArrayList of listeners and the addChangeListener() and notifyListeners() methods work
• After that we’ll take a look at how the memento functionality works
• Then we’ll move on from this example to the next, which should be a better solution
![Page 33: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/33.jpg)
33
The ArrayList of Listeners
• On the next overhead those parts of FactoryModel having to do directly with the ArrayList of listeners is shown
![Page 34: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/34.jpg)
34
• public class FactoryModel {• …• private ArrayList listeners = new ArrayList();• …• public void addChangeListener(ChangeListener listener)
{• listeners.add(listener);• }• …• public void notifyListeners() {• for (int i = 0; i < listeners.size(); i++)• ((ChangeListener)
listeners.get(i)).stateChanged(new ChangeEvent(this));• }
![Page 35: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/35.jpg)
35
• By way of introductory explanation, what they authors have done is make FactoryModel “listenable”
• Making it observable would have been syntactically clear and better
• The point is that there is no such thing as listenability except by “inventing” it
![Page 36: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/36.jpg)
36
• That’s what they’ve done here• You don’t extend a listenable class• You simply implement methods that make it
possible to have a collection of listeners associated with FactoryModel
• Then look at the notifyListeners() method• You explicitly call stateChanged() on each
associate listener
![Page 37: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/37.jpg)
37
• In other words, you’re not relying on a callback sequence
• You’re coding it yourself• The more I look at this the less I like it
![Page 38: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/38.jpg)
38
• I’m getting ahead of myself, because we haven’t discussed how the mementos actually work yet, but this is a call that changes the state by adding a memento
• The point is, this is where a call to notifyListeners() is located
• public void setLocations(ArrayList list) • {• mementos.push(list);• notifyListeners();• }
![Page 39: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/39.jpg)
39
• In short, in an MVC design, when the model/state/mementos changed, you would observe that fact and the observers would “act”
• Here, we’re short-circuiting this by notifying listeners to act when the state changes
![Page 40: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/40.jpg)
40
• The remaining question is, what is or are the actual listeners for this application?
• What do they do when the state of the FactoryModel changes and they are notified?
• We won’t arrive at the answer to this question until later…
![Page 41: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/41.jpg)
41
• Anyway, this is the general design for how the authors have implemented their example
• In order to follow the rest of the explanation of the handling of mementos, it’s simply necessary to accept this and see what else they have done
![Page 42: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/42.jpg)
42
Implementing Memento in the First Example
• What is a memento?• It is an ArrayList which holds the points
specifying the locations of the machines in the work area for a given application state
• The stack in the FactoryModel potentially holds multiple instances of such ArrayLists
![Page 43: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/43.jpg)
43
• Here is the code at the beginning of the FactoryModel class
• It shows the declarations of the Stack of mementos and the ArrayList of listeners
• It also shows the default constructor• In it the Stack is constructed and the initial,
empty state is constructed and pushed onto it
![Page 44: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/44.jpg)
44
• public class FactoryModel• {• private Stack mementos;• private ArrayList listeners = new ArrayList();• public FactoryModel()• {• mementos = new Stack();• mementos.push(new ArrayList());• }• …
![Page 45: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/45.jpg)
45
• Most of the code shown is unremarkable• The most important thing to notice is this line of
code:• mementos.push(new ArrayList());• A memento is an instance of ArrayList• When the model is constructed, the empty state is
put onto the stack• The default constructor is used to create an empty
ArrayList and push it onto the stack
![Page 46: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/46.jpg)
46
• Notice that in general, there is no need for a state to be named
• The states are not named instances of objects• They are simply instances of ArrayList
constructed at the moment
![Page 47: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/47.jpg)
47
Ordering of mementos
• The identifying feature of states which is important to the application is where in the stack they occur, since a stack is an ordered data structure
• In other words, going down the stack means going back in time
![Page 48: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/48.jpg)
48
• The book summarizes the rest of the methods in the FactoryModel class as follows:
• They maintain the stack of mementos• They deal with events that make changes
![Page 49: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/49.jpg)
49
Adding a Machine to the Representation
• Code for the FactoryModel add() method is shown on the following overhead, for example
• Adding a machine to the visualization means adding a point to the list of machine locations
• When this change occurs, the listeners are notified
• Comments have been added to the code
![Page 50: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/50.jpg)
50
• public void add(Point location)• {• /* Get a copy of the old state by peeking at the top of
the stack of mementos. */• List oldLocs = (List) mementos.peek();• /* Create a new state, the same as the old. */• List newLocs = new ArrayList(oldLocs);• /* Add the new location to the new state. */• newLocs.add(0, location);• /* Push the new state onto the stack. */• mementos.push(newLocs);• /* Notify the listeners of changes to the state. */• notifyListeners();• }
![Page 51: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/51.jpg)
51
Ordering in Mementos
• It is possible to iterate over lists without worrying about the order of their contents
• It is also possible to refer to elements of the list by index
• In the previous method, a location was added to a memento ArrayList at position 0
![Page 52: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/52.jpg)
52
• What’s happening here is a version of the painter’s algorithm
• Each succeeding machine and location that becomes part of a state is put “on top”
• That way, if visual representations overlap, the thing that is “on top” of the ArrayList will be displayed on top of the other representations in the GUI
![Page 53: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/53.jpg)
53
Getting All Locations for a Current State
• The code for the getLocations() method is given on the following overhead
• Responding to events and repainting the work area will require access to all of the current machine locations
• The method returns the list of current machine locations—the list at the top of the memento stack
• Notice that peek() is not the same as popping the stack
![Page 54: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/54.jpg)
54
• public List getLocations()• {• return (List) mementos.peek();• }
![Page 55: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/55.jpg)
55
Implementing Undo Functionality
• Next the book considers the undo() method in the FactoryModel class
• This is the method that triggers a change in state back to the previous one
• Like the add() method given above, the undo() method will notify any listeners
• The book deals with this method as a challenge
![Page 56: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/56.jpg)
56
• Challenge 19.1• Write the code for the FactoryModel class’s
undo() method.
![Page 57: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/57.jpg)
57
• Solution 19.1• Here is one implementation of undo() for
FactoryModel• [See the code on the following overhead• Comment mode on:• It is clear that these two methods could easily be
merged• The reason for a separate canUndo() will become
evident later]
![Page 58: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/58.jpg)
58
• public boolean canUndo()• {• return mementos.size() > 1;• }• public void undo()• {• if(!canUndo()) return;• mementos.pop();• notifyListeners();• }
![Page 59: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/59.jpg)
59
• Solution 19.1, continued:• This code is careful to ignore undo() requests
if the stack is down to its initial state with a single memento.
• The top of the stack is always the current state, so the undo() code has to pop the stack to expose the previous memento.
![Page 60: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/60.jpg)
60
• Comment mode on:• Note that popping the stack means throwing
away the current state, because you don’t capture the state that is popped
• You’re not supporting redo functionality• We don’t have time to worry about it, but
thinking about it suggests that supporting both undo and redo would be an interesting challenge
![Page 61: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/61.jpg)
61
• Solution 19.1, continued:• When you write a createMemento() method,
you should convince yourself or your colleagues that the method returns all the information necessary to reconstruct the receiving object.
• In this example, a machine simulator can reconstruct itself from a clone, and a factory simulator can reconstruct itself from a list of machine simulator clones.
![Page 62: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/62.jpg)
62
• Solution 19.1• Comment mode on• What the authors are trying to say in the previous
paragraph is not clear• They have claimed that the only memento you need for
this application is a list of machine locations• Presumably, the picture of each machine in the
visualization is just a stock image• Why they’re now babbling about clones and lists of
clones is not clear
![Page 63: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/63.jpg)
63
• Back to the material in the text:• The previous UML diagram and code examples
gave some idea of the FactoryModel class• It contains methods that change the state of the
model• It also contains methods to register listeners and
notify them when the state changes• For better or worse, we still haven’t been told
about the listeners
![Page 64: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/64.jpg)
64
• The book suggests that overall, the visualization can be structured using a model-view-controller type design
• A UML diagram is given on the following overhead showing how the visualization and the factory model are implemented in separate classes
• The meaning of the VisMediator class and the various relationships shown will be outlined afterwards
![Page 65: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/65.jpg)
65
![Page 66: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/66.jpg)
66
• The application reacts to events by means of a mouse listener in the work area and listeners for the Add and Undo buttons
• Part of the role of the VisMediator class is to hold the functionality that responds to events
• In other words, the VisMediator contains the controller functionality
![Page 67: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/67.jpg)
67
• An expanded UML diagram showing the relationships between the FactoryModel, Visualization, and VisMediator classes will be shown shortly
• The Visualization class has methods related to creating the GUI of the application
• It can respond to changes in the factory model in order to update the graphical representation
![Page 68: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/68.jpg)
68
• The VisMediator class is the locus for listening• In other words, handling GUI events is offloaded
into this new class• The book expresses the function of the
VisMediator class in this way:• “The mediator translates GUI events into factory
changes.”• The relationships are shown in the UML diagram
on the following overhead
![Page 69: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/69.jpg)
69
![Page 70: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/70.jpg)
70
What the Book Has and Has Not Done
• It is important to note that for all practical purposes in this new design there has been no change in the FactoryModel
• In other words, it will still have listeners added to it
• And when you look at the Visualization class, it contains a stateChanged() method
• Although it’s not shown in the UML diagram, it effectively implements ChangeListener
![Page 71: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/71.jpg)
71
• The overall story is this:• Listening for controller functionality has been
offloaded into VisMediator• However, the view side of this design is still
driven by listening rather than observing• This is moderately disappointing since the
book introduces Observer in chapter 9 and Memento in chapter 19
![Page 72: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/72.jpg)
72
Code for the New Example
• The book now shows the relationship between the Visualization class and the VisMediator classes
• The Visualization class has a reference to the VisMediator class
• The Visualization class has a method to create an Undo button and adds to it a listener belonging to the VisMediator class
• This is shown on the next overhead
![Page 73: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/73.jpg)
73
• protected JButton undoButton()• {• if(undoButton == null)• {• undoButton = ui.createButtonCancel();• undoButton.setText(“Undo”);• undoButton.setEnabled(false);• undoButton.addActionListener(mediator.undoAction());• }• return undoButton;• }
![Page 74: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/74.jpg)
74
• In summary, the previous code shows that the mediator is the listener for a button in the Visualization GUI
![Page 75: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/75.jpg)
75
• The book states that the mediator then informs the factory of requested changes using the code shown on the following overhead
• VisMediator has a reference to the FactoryModel which it received as a construction parameter
• VisMediator has a button listener• The button listener calls the undo() method shown• This method wraps a call to a method named undo() in
the FactoryModel class which actually changes the model
![Page 76: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/76.jpg)
76
• private void undo(ActionEvent e)• {• factoryModel.undo();• }
![Page 77: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/77.jpg)
77
• The constructor for Visualization is shown on the following overhead
• The third line of code shows how the VisMediator is constructed with a factory model reference and how the Visualization receives a reference to this
• The fourth line of code shows the Visualization being added to the factory model as a change listener
![Page 78: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/78.jpg)
78
• public Visualization(UI ui)• {• super(new BorderLayout));• this.ui = ui;• mediator = new
VisMediator(factoryModel);• factoryModel.addChangeListener(this);• add(machinePanel(),
BorderLayout.CENTER);• add(buttonPanel(), BorderLayout.SOUTH);• }
![Page 79: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/79.jpg)
79
How It Works, Again
• The VisMediator listens to the GUI• The VisMediator has access to change the
FactoryModel• The Visualization listens to the FactoryModel• A change in the FactoryModel is propagated to
the Visualization by calling the stateChanged() method on it
![Page 80: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/80.jpg)
80
• The sequence of events when the Undo button is clicked in the GUI can be modeled as shown in the following sequence diagram
![Page 81: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/81.jpg)
81
![Page 82: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/82.jpg)
82
• A state change, like undo, means that all of the current pictures of machines have to be removed from the Visualization
• Then pictures at all of the locations in the previous state have to be presented
• The Undo button has to be enabled/disabled according to whether a further undo is possible
![Page 83: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/83.jpg)
83
• Challenge 19.2• Write the stateChanged() method for the
Visualization class.
![Page 84: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/84.jpg)
84
• Solution 19.2• One solution is:• [See code on the next overhead.]
![Page 85: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/85.jpg)
85
• public void stateChanged(ChangeEvent e)• {• machinePanel().removeAll();• List locations = factoryModel.getLocations();• for(int i = 0; i < locations.size(); i++)• {• Point p = (Point) locations.get(i);• machinePanel().add(createPictureBox(p));• }• undoButton().setEnabled(factoryModel.canUndo());• repaint();• }
![Page 86: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/86.jpg)
86
• Note three things in the previous code:• 1. When generating the visual representation,
the list of locations is traversed in order• In other words, a for loop, not a for each loop
is used• This makes sure that the most recent machine
images are on top
![Page 87: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/87.jpg)
87
• 2. Also, there is a createPictureBox() method that we haven’t seen before
• This apparently is the method that generates the standard representation of a machine in the visualization
• 3. This is when you find out why they implemented canUndo() earlier as a separate method—so it can be called here
![Page 88: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/88.jpg)
88
• The book’s summary of the foregoing example is this:
• Mementos, records of visualization state, are being stored as objects in a stack while the program is running
• It is also possible that more persistent storage of state may be desirable
![Page 89: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/89.jpg)
89
Memento Durability
• This subsection can be summarized very succinctly
• If you want persistent storage of state, in Java the solution is to save memento objects in secondary storage using serializability
• In the interests of completeness, the book’s observations and examples will be presented
![Page 90: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/90.jpg)
90
• The book observes that it may be desirable to store state over widely varying periods of time
• The previous example was about storing it during the course of a program run
• A program run can be referred to as a session
![Page 91: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/91.jpg)
91
• If state is to be stored between sessions, the period of time involved could range from days, to weeks, to months, to years…
• State can be saved in the form of a persistent serializable object, or perhaps a text string or other data in secondary storage
![Page 92: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/92.jpg)
92
• Challenge 19.3• Write down two reasons that might drive you
to save a memento in a file rather than as an [a runtime] object.
![Page 93: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/93.jpg)
93
• Solution 19.3• Storing a memento as an object assumes that
the application will still be running when the user wants to restore the original object.
• Reasons that will force you to save a memento to persistent storage include the following.
![Page 94: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/94.jpg)
94
• The ability to restore an object’s state has to survive a system crash.
• You anticipate that the user will exit the system and will want to resume work later.
• You need to reconstruct an object on another computer.
• [End of Solution 19.3.]
![Page 95: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/95.jpg)
95
Persisting Mementos Across Sessions
• The book next proposes a new visualization, Visualization2, which is a subclass of the original visualization
• Visualization2 will have menu options to “Save As…” and “Restore From…”
• These are analogous to the save and load features of Togiz Kumalak from CSCE 202
![Page 96: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/96.jpg)
96
• The domain specific difference is simply in what’s being saved and restored
• There are also potentially minor syntactical differences in how the authors implement the listeners compared to the model used by the orange book (CSCE 202)
• A screen shot showing these menu options is given below
![Page 97: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/97.jpg)
97
![Page 98: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/98.jpg)
98
Implementation
• On the overhead following the next one, code for the new Visualization2 class is given
• In that code you will notice that the listeners for the menu options come from the VisMediator
• The code for VisMediator will be pursued after the code for Visualization2
![Page 99: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/99.jpg)
99
• Depending on how closely you’re following the book’s materials, the following observations may also be important
• In addition to the printed code in the text, source code can be downloaded from the book’s Web site
• Unfortunately, the Visualization2 and VisMediator code on the Web site differ from that given in the book
• What is presented here is based on the printed version in the text
![Page 100: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/100.jpg)
100
• package com.oozinoz.visualization;
• import java.awt.event.*;• import javax.swing.*;• import com.oozinoz.ui.*;
• public class Visualization2 extends Visualization • {• public Visualization2(UI ui) • {• super(ui);• }
![Page 101: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/101.jpg)
101
• public JMenuBar menus() • {• JMenuBar menuBar = new JMenuBar();• JMenu menu = new JMenu("File");• menuBar.add(menu);
• JMenuItem menuItem = new JMenuItem("Save As...");• menuItem.addActionListener(mediator.saveAction());• menu.add(menuItem);
• menuItem = new JMenuItem("Restore From...");• menuItem.addActionListener(mediator.restoreAction());• menu.add(menuItem);
• return menuBar;• }
![Page 102: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/102.jpg)
102
• 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);• }
![Page 103: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/103.jpg)
103
• By this time it’s possible to have forgotten what, exactly, you’re saving
• What is being saved in serializable form are the lists of locations representing the current state of the visualization
• There is no stack present• It would be up to the user to name each separate
state as it’s saved, and restore it by name later, if desired
![Page 104: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/104.jpg)
104
• On the overhead following the next one, the code for the saveAction() method of the VisMediator is given
• This is the method that is called in Visualization2 in order to add a listener to the menu item
• The book uses an anonymous listener (unfortunately)
![Page 105: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/105.jpg)
105
• This anonymous listener relies on a save() method in VisMediator, which is also shown
• It is this method that finally does the actual work of saving using serializability
• You may want to take a look at the code as presented on the Web site
• It makes the relationship between the Visualization2 and VisMediator classes clearer
• The code from the text is given on the following overheads
![Page 106: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/106.jpg)
106
• public ActionListener saveAction()• {• return new ActionListener()• {• public void actionPerformed()• {• try• {• VisMediator.this.save((Component)e.getSource());• }• catch(Exception ex)• {• System.out.println(“Failed save: “ + ex.getMessage());• }• }• };• }
![Page 107: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/107.jpg)
107
• public void save(Component source) throws Exception • {• JFileChooser dialog = new JFileChooser();• dialog.showSaveDialog(source);• if (dialog.getSelectedFile() == null)• return;• • FileOutputStream out = null;• ObjectOutputStream s = null;• try • {• out = new FileOutputStream(dialog.getSelectedFile());• s = new ObjectOutputStream(out);• s.writeObject(factoryModel.getLocations());• } • finally • {• if (s != null)• s.close();• }• }
![Page 108: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/108.jpg)
108
• Challenge 19.4• Write the code for the restoreAction() method
of the VisMediator class
![Page 109: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/109.jpg)
109
• Solution 19.4• One solution is:• Comment mode on:• The challenge asks for the code for the
restoreAction() method• The solution shows the code for the restore()
method, without giving the restoreAction() method
![Page 110: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/110.jpg)
110
• Comment mode continued:• The book notes that the restore() method (not
the restoreAction() method, since that’s not shown) is analogous to the save() method
• It would also be the case that the restoreAction() method would be analogous
• The code given by the book as a solution is shown on the next overhead
![Page 111: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/111.jpg)
111
• public void restore(Component source) throws Exception • {• JFileChooser dialog = new JFileChooser();• dialog.showOpenDialog(source);• if (dialog.getSelectedFile() == null)• return;• • FileInputStream out = null;• ObjectInputStream s = null;• try • {• out = new FileInputStream(dialog.getSelectedFile());• s = new ObjectInputStream(out);• ArrayList list = (ArrayList) s.readObject();• factoryModel.setLocations(list);• } • finally • {• if (s != null)• s.close();• }• }
![Page 112: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/112.jpg)
112
• Continuing with book’s material:• The book states that in the original book,
Design Patterns, the intent of the Memento design pattern is stated as follows:
• “Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.”
![Page 113: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/113.jpg)
113
• Challenge 19.5• In this case, we used Java serialization to write
to a file in binary format. • Suppose that we had written it to XML format
(textual) instead. • Write a short statement of whether, in your
opinion, saving a memento in textual form would violate encapsulation.
![Page 114: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/114.jpg)
114
• Solution 19.5• To encapsulate is to limit access to an object’s
state and operations.• Saving an object, such as a collection of factory
[machine] location points, in textual form exposes the object’s data and allows anyone with a text editor to change the object’s state.
• Thus, saving an object in XML form violates encapsulation, at least to some degree.
![Page 115: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/115.jpg)
115
• Violation of encapsulation through persistent storage may be a concern in practice, depending on your application.
• To address this threat, you might limit access to the data, as is common in a relational database.
• In other cases, you might encrypt the data, as is common when transmitting sensitive HTML text.
![Page 116: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/116.jpg)
116
• The point here is not whether the words encapsulation and memento apply to a design but rather the real importance of ensuring data integrity while supporting the data’s storage and transmission.
![Page 117: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/117.jpg)
117
• Comment mode on:• This is my take on what the authors have just
said:• The original question about storing in textual
form is a red herring• First of all, you might ask, why store object
state in textual form when Java serializability is available anyway?
![Page 118: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/118.jpg)
118
• Secondly, their follow-up observation is essentially this:
• Even if you use serializability, somebody with a binary editor could still mess with the state of a stored object
• Ultimately, if you are going to save things in secondary storage, and security is a concern, you will have to limit access to the data
![Page 119: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/119.jpg)
119
Another Example
• No other example will be given
![Page 120: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/120.jpg)
120
Lasater’s UML
• Lasater’s UML diagram is included for the sake of completeness
• It doesn’t seem to add anything to understanding the pattern
![Page 121: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/121.jpg)
121
![Page 122: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/122.jpg)
122
Summary
• The Memento design pattern lets you capture an object’s state so that the object can be restored later
• The need to use the memento pattern is most frequently occasioned by the need to support an “undo” function in an application
• In this case, the state may be saved in an object which is part of the program and only persists as long as the program is running
![Page 123: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/123.jpg)
123
• It may also be desirable to be able to save and restore the state of an object between program runs
• Potentially, such storage can persist for long periods of time
• Typically, the solution is to save a representation of the object to secondary storage
• Java serializability supports this capability
![Page 124: Chapter 19 Memento](https://reader035.fdocuments.us/reader035/viewer/2022062323/56816641550346895dd9b253/html5/thumbnails/124.jpg)
124
The End