使用备忘录模式实现Undo和Redo
备忘录模式有三个角色。
1.发起人(Originator)角色:负责创建一个备忘录,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。实现其他业务功能。
2.备忘录(Memento)角色:负责存储发起人的内部状态。
3.管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
/** * 发起人角色 * */public class UnRedoOriginator { private String state; public UnRedoOriginator() { } public void setState(String state) { this.state = state; } public String getState() { return state; } public Memento createMemento() { return new Memento(state); } public void restoreMemento(Memento m) { if (m != null) { this.setState(m.getState()); } else { System.out.println("没有状态可恢复"); } }}
/** * 备忘录 * */public class Memento { private String state; public Memento(String state) { this.state = state; } public void setState(String state) { this.state = state; } public String getState() { return state; }}
/** * 可undo和redo的备忘录管理者 * */public class UnRedoCaretaker { /* 备忘列表 */ private List<Memento> mementoList; /* 备忘列表容量,备忘列表容量 = 最大后退次数 + 1 */ private int capacity = 3; /* 后退索引 */ private int undoIndex = -2; /* 前进索引 */ private int redoIndex = 0; public UnRedoCaretaker() { this.mementoList = new LinkedList<>(); } public UnRedoCaretaker(int capacity) { this(); this.capacity = capacity; } /** * 添加备忘 * * @param memento */ public void addMemento(Memento memento) { // 添加备忘前,移除当前状态之后的备忘 for (int i = this.mementoList.size() - 1; i > this.undoIndex + 1; i--) { this.mementoList.remove(i); } if (this.mementoList.size() >= this.capacity) { this.mementoList.remove(0); } this.mementoList.add(memento); this.undoIndex = this.mementoList.size() - 2; this.redoIndex = this.mementoList.size(); } /** * 后退操作 * * @return */ public Memento undo() { Memento result = null; if (this.undoIndex >= 0 && this.undoIndex < this.mementoList.size() - 1) { result = this.mementoList.get(this.undoIndex); this.undoIndex--; this.redoIndex--; } return result; } /** * 前进操作 * * @return */ public Memento redo() { Memento result = null; if (this.redoIndex > 0 && this.redoIndex < this.mementoList.size()) { result = this.mementoList.get(this.redoIndex); this.redoIndex++; this.undoIndex++; } return result; }}
把发起人角色与备忘录管理者角色聚合在一起,修改发起人角色类。
/** * 发起人角色 * */public class UnRedoOriginator { private String state; private UnRedoCaretaker caretaker; public UnRedoOriginator() { this.caretaker = new UnRedoCaretaker(3); } private void setState(String state) { this.state = state; } public String getState() { return state; } private Memento createMemento() { return new Memento(state); } private void restoreMemento(Memento m) { if (m != null) { this.setState(m.getState()); } else { System.out.println("没有状态可恢复"); } } public void setAndStoreState(String state) { this.setState(state); caretaker.addMemento(this.createMemento()); } public void undo() { this.restoreMemento(caretaker.undo()); } public void redo() { this.restoreMemento(caretaker.redo()); }}
测试。
/** * 测试 undo和redo * */public class TestUnRedo { public static void main(String[] args) { UnRedoOriginator or = new UnRedoOriginator(); /* 未设置状态前进后退 */ or.undo(); or.redo(); /* 连续添加操作 */ System.out.println(); int num = 1; operation(or, num++); operation(or, num++); operation(or, num++); operation(or, num++); /* 后退次数超过可后退次数 */ back(or); back(or); back(or); /* 后退时添加新操作,然后再后退 */ System.out.println(); operation(or, num++); back(or); forward(or); forward(or);// 前进次数超过可前进次数 /* 后退时添加新操作,然后redo */ System.out.println(); back(or); operation(or, num++); forward(or); } private static void operation(UnRedoOriginator or, int name) { System.out.println("*******操作*******"); or.setAndStoreState("操作" + name); System.out.println("当前状态:" + or.getState()); } private static void back(UnRedoOriginator or) { System.out.println("-------后退-------"); or.undo(); System.out.println("当前状态:" + or.getState()); } private static void forward(UnRedoOriginator or) { System.out.println("=======前进======="); or.redo(); System.out.println("当前状态:" + or.getState()); }}
运行结果如下。
没有状态可恢复没有状态可恢复*******操作*******当前状态:操作1*******操作*******当前状态:操作2*******操作*******当前状态:操作3*******操作*******当前状态:操作4-------后退-------当前状态:操作3-------后退-------当前状态:操作2-------后退-------没有状态可恢复当前状态:操作2*******操作*******当前状态:操作5-------后退-------当前状态:操作2=======前进=======当前状态:操作5=======前进=======没有状态可恢复当前状态:操作5-------后退-------当前状态:操作2*******操作*******当前状态:操作6=======前进=======没有状态可恢复当前状态:操作6
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。