Memento概述
UML概述

玩具代码案例1 - 模拟浏览器的回退&前进操作
备忘录发起者
Browser
package online.javabook.gof.behavioral.patterns5.memento1.browser.context;import online.javabook.gof.behavioral.patterns5.memento1.browser.memento.History;import online.javabook.gof.behavioral.patterns5.memento1.browser.memento.Memento;public class Browser {private History history = new History();private String url;public void go(String url) {this.url = url;history.add(new Memento(url));System.out.println("->" + url);}public void back() {Memento memento = history.getUndo();this.url = memento.getState();System.out.println("<-" + url);}public void forward() {Memento memento = history.getRedo();this.url = memento.getState();System.out.println("->" + url);}}
备忘录回放
History
package online.javabook.gof.behavioral.patterns5.memento1.browser.memento;import java.util.ArrayList;import java.util.List;public class History {private int index = -1;private List<Memento> mementoList = new ArrayList<Memento>();public void add(Memento state){mementoList.add(state);index++;}public Memento get(int index){return mementoList.get(index);}public Memento getUndo() {if (index == -1) {return null;}index = Math.max(0, --index);return mementoList.get(index);}public Memento getRedo() {if (index == mementoList.size()) {return null;}index = Math.min(mementoList.size() - 1, ++index);return mementoList.get(index);}}
备忘录状态
Memento
package online.javabook.gof.behavioral.patterns5.memento1.browser.memento;public class Memento {private String url;public Memento(String url){this.url = url;}public String getState(){return url;}}
备忘录测试
Main
package online.javabook.gof.behavioral.patterns5.memento1.browser.app;import online.javabook.gof.behavioral.patterns5.memento1.browser.context.Browser;public class Main {public static void main(String[] args) {Browser browser = new Browser();browser.go("http://www.1.com");browser.go("http://www.2.com");browser.go("http://www.3.com");browser.go("http://www.4.com");browser.go("http://www.5.com");browser.go("http://www.6.com");browser.back();browser.back();browser.back();browser.back();browser.back();browser.back();browser.back();browser.forward();browser.forward();browser.forward();browser.forward();browser.forward();browser.forward();browser.forward();browser.back();browser.back();browser.back();}}
Console
->http://www.1.com->http://www.2.com->http://www.3.com->http://www.4.com->http://www.5.com->http://www.6.com<-http://www.5.com<-http://www.4.com<-http://www.3.com<-http://www.2.com<-http://www.1.com<-http://www.1.com<-http://www.1.com->http://www.2.com->http://www.3.com->http://www.4.com->http://www.5.com->http://www.6.com->http://www.6.com->http://www.6.com<-http://www.5.com<-http://www.4.com<-http://www.3.com
玩具代码案例2 - 图形编辑器与备忘录模式
图形编辑器中的redo/undo可能是备忘录模式的源头,这个案例中我们结合了命令模式(命令即状态)和备忘录模式
备忘录发起者
GraphEditor
package online.javabook.gof.behavioral.patterns5.memento2.grapheditor.context;import online.javabook.gof.behavioral.patterns5.memento2.grapheditor.command.ColorCommand;import online.javabook.gof.behavioral.patterns5.memento2.grapheditor.command.IGraphCommand;import online.javabook.gof.behavioral.patterns5.memento2.grapheditor.command.MoveCommand;import online.javabook.gof.behavioral.patterns5.memento2.grapheditor.memen.GraphCommandHistory;import online.javabook.gof.behavioral.patterns5.memento2.grapheditor.memen.GraphCommandMemento;import java.awt.*;public class GraphEditor {private GraphCommandHistory history = new GraphCommandHistory();private Shape shape = new Shape();public void color(Color newColor) {IGraphCommand command = new ColorCommand(newColor);command.execute(shape);GraphCommandMemento memento = new GraphCommandMemento(command);history.add(memento);System.out.println("->" + shape);}public void move(Point newPoint) {IGraphCommand command = new MoveCommand(newPoint);command.execute(shape);GraphCommandMemento memento = new GraphCommandMemento(command);history.add(memento);System.out.println("->" + shape);}public void undo() {GraphCommandMemento memento = history.getUndo();IGraphCommand command = memento.getState();command.execute(shape);System.out.println("<-" + shape);}public void redo() {GraphCommandMemento memento = history.getRedo();IGraphCommand command = memento.getState();command.execute(shape);System.out.println("->" + shape);}}
备忘录回放
History
package online.javabook.gof.behavioral.patterns5.memento2.grapheditor.memen;import java.util.ArrayList;import java.util.List;public class GraphCommandHistory {private int index = -1;private List<GraphCommandMemento> mementoList = new ArrayList<GraphCommandMemento>();public void add(GraphCommandMemento state){mementoList.add(state);index++;}public GraphCommandMemento get(int index){return mementoList.get(index);}public GraphCommandMemento getUndo() {if (index == -1) {return null;}index = Math.max(0, --index);return mementoList.get(index);}public GraphCommandMemento getRedo() {if (index == mementoList.size()) {return null;}index = Math.min(mementoList.size() - 1, ++index);return mementoList.get(index);}}
备忘录状态
Memento
package online.javabook.gof.behavioral.patterns5.memento2.grapheditor.memen;import online.javabook.gof.behavioral.patterns5.memento2.grapheditor.command.IGraphCommand;public class GraphCommandMemento {private IGraphCommand graphCommand;public GraphCommandMemento(IGraphCommand graphCommand){this.graphCommand = graphCommand;}public IGraphCommand getState(){return graphCommand;}}
备忘录命令
IGraphCommand
package online.javabook.gof.behavioral.patterns5.memento2.grapheditor.command;
import online.javabook.gof.behavioral.patterns5.memento2.grapheditor.context.Shape;
public interface IGraphCommand {
void execute(Shape shape);
}
ColorCommand
package online.javabook.gof.behavioral.patterns5.memento2.grapheditor.command;
import online.javabook.gof.behavioral.patterns5.memento2.grapheditor.context.Shape;
import java.awt.*;
public class ColorCommand implements IGraphCommand {
private Color color;
public ColorCommand(Color newColor) {
this.color = newColor;
}
@Override
public void execute(Shape shape) {
shape.setColor(color);
}
}
MoveCommand
package online.javabook.gof.behavioral.patterns5.memento2.grapheditor.command;
import online.javabook.gof.behavioral.patterns5.memento2.grapheditor.context.Shape;
import java.awt.*;
public class MoveCommand implements IGraphCommand {
private Point point;
public MoveCommand(Point newPoint) {
this.point = newPoint;
}
@Override
public void execute(Shape shape) {
shape.setPoint(point);
}
}
备忘录测试
Main
package online.javabook.gof.behavioral.patterns5.memento2.grapheditor.app;
import online.javabook.gof.behavioral.patterns5.memento2.grapheditor.context.GraphEditor;
import java.awt.*;
public class Main {
public static void main(String[] args) {
GraphEditor graphEditor = new GraphEditor();
graphEditor.color(Color.red);
graphEditor.color(Color.orange);
graphEditor.color(Color.yellow);
graphEditor.move(new Point(1,1));
graphEditor.move(new Point(2,2));
graphEditor.move(new Point(3,3));
graphEditor.undo();
graphEditor.undo();
graphEditor.redo();
graphEditor.redo();
}
}
Console
->Shape{color=java.awt.Color[r=255,g=0,b=0], point=java.awt.Point[x=0,y=0]}
->Shape{color=java.awt.Color[r=255,g=200,b=0], point=java.awt.Point[x=0,y=0]}
->Shape{color=java.awt.Color[r=255,g=255,b=0], point=java.awt.Point[x=0,y=0]}
->Shape{color=java.awt.Color[r=255,g=255,b=0], point=java.awt.Point[x=1,y=1]}
->Shape{color=java.awt.Color[r=255,g=255,b=0], point=java.awt.Point[x=2,y=2]}
->Shape{color=java.awt.Color[r=255,g=255,b=0], point=java.awt.Point[x=3,y=3]}
<-Shape{color=java.awt.Color[r=255,g=255,b=0], point=java.awt.Point[x=2,y=2]}
<-Shape{color=java.awt.Color[r=255,g=255,b=0], point=java.awt.Point[x=1,y=1]}
->Shape{color=java.awt.Color[r=255,g=255,b=0], point=java.awt.Point[x=2,y=2]}
->Shape{color=java.awt.Color[r=255,g=255,b=0], point=java.awt.Point[x=3,y=3]}

