备忘录模式有三个角色。
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
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。