1.题目分析 首先需要一个实体类来代表一枚象棋的基本信息,包含象棋的名字/当前坐标 其次需要一个备忘录类来保存象棋的信息,这个类应当含有象棋类的要保存的字段,并且该类对外封闭 由于备忘录类是对外封闭的,所以应当由一个备忘录管理者类,来负责创建和恢复象棋的备忘录 客户端不与备忘录类耦合,而是借用备忘录管理类来管理备忘录 2.UML图
3.代码 象棋实体类
代码语言:javascript复制package 备忘录模式;
public class Chessman {
private String name;
private int x;
private int y;
public ChessmanMemento CreateMemento() {
return new ChessmanMemento(name, x, y);
}
public void setMemento(ChessmanMemento chessmanMemento) {
this.name = chessmanMemento.getName();
this.x = chessmanMemento.getX();
this.y = chessmanMemento.getY();
}
public Chessman() {
}
public Chessman(String name, int x, int y) {
this.name = name;
this.x = x;
this.y = y;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String toString() {
return "Chessman{"
"name='" name '''
", x=" x
", y=" y
'}';
}
}
象棋备忘录 用于保存象棋的状态信息
代码语言:javascript复制package 备忘录模式;
public class ChessmanMemento {
private String name;
private int x;
private int y;
public ChessmanMemento(String name, int x, int y) {
this.name = name;
this.x = x;
this.y = y;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
备忘录负责人 管理备忘录 隐藏备忘录内部实现
代码语言:javascript复制package 备忘录模式;
public class MementoCaretaker {
private ChessmanMemento chessmanMemento;
public ChessmanMemento getChessmanMemento() {
return chessmanMemento;
}
public void setChessmanMemento(ChessmanMemento chessmanMemento) {
this.chessmanMemento = chessmanMemento;
}
}
象棋悔棋备忘录测试类
代码语言:javascript复制package 备忘录模式;
public class Test {
public static void main(String[] args) {
Chessman chessman = new Chessman("马", 1, 1);
System.out.println("象棋初始状态-->" chessman);
MementoCaretaker mementoCaretaker = new MementoCaretaker();
mementoCaretaker.setChessmanMemento(chessman.CreateMemento());
chessman.setX(666);
chessman.setY(666);
System.out.println("象棋修改状态-->" chessman);
chessman.setMemento(mementoCaretaker.getChessmanMemento());
System.out.println("象棋恢复状态-->" chessman);
}
}
运行结果
4.总结:
- 该模式的优缺点,特别从开闭原则论述 优点:利用备忘录管理者类,保持了象棋的封闭性,没有破坏其封装。保存了象棋的内部状态,以便在需要的时候恢复状态 缺点:如果类的信息太多,会十分消耗资源
- 编程中遇到的问题及解决方法: 该模式在不同的场景下有改进的几个方面,比如:备忘录管理者类,其字段备忘录可以改为一个Map类型的,key为唯一的字段属性,value为保存的备忘录对象,这样就可以根据Key来恢复任意一个状态,Github的版本控制就是这个原理,每一个版本都有对应的一个哈希串,可以回退到任意一个版本。 可以结合原型模式 备忘录来处理相应的需求,以减少资源的消耗