简介
又称快照模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并且该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态
UML图
应用场景
- 允许用户取消不确定或者错误的操作,能够恢复到原先的状态
- 游戏存档、棋盘游戏悔棋,数据库事务回滚等
示例
游戏存档
- Originator:
public class GameOriginator {
/**
* 角色名称
*/
private String name;
/**
* 血量
*/
private int live;
/**
* 攻击力
*/
private int attack;
// 初始化状态
public GameOriginator(String name) {
this.name = name;
this.live = 100;
this.attack = 1;
}
/**
* 进攻
*/
public int fight() {
if (this.live <= 0) {
System.out.println("你输了!游戏结束。");
return -1;
}
// 每次攻击少2滴血
this.live -= 2;
// 攻击力增加5
this.attack += 5;
return 0;
}
/**
* 防御
*/
public void defense() {
// 血量增加1
this.live += 1;
}
/**
* 保存
*
* @return
*/
public GameMemento saveState() {
return new GameMemento(live, attack);
}
public void recoveryState(GameMemento gameMemento) {
this.live = gameMemento.getLive();
this.attack = gameMemento.getAttack();
}
public void display() {
System.out.println("角色名称:" + name + ",血量:" + live + ",攻击力:" + attack);
}
}
- Memento:保存角色的关键状态
public class GameMemento {
private int live;
private int attack;
public GameMemento(int live, int attack) {
this.live = live;
this.attack = attack;
}
public int getLive() {
return live;
}
public int getAttack() {
return attack;
}
}
- Caretaker:游戏管理界面
public class GameCaretaker {
private GameMemento gameMemento;
public GameMemento getGameMemento() {
return gameMemento;
}
public void setGameMemento(GameMemento gameMemento) {
this.gameMemento = gameMemento;
}
}
- 运行
public class Main {
public static void main(String[] args) {
// 创建游戏角色
GameOriginator gameRole = new GameOriginator("大大怪");
gameRole.display();
// 连击10次
for (int i = 0; i < 10; i++) {
gameRole.fight();
}
// 防御
gameRole.defense();
gameRole.display();
// 保存状态
System.out.println("存档。。。。");
GameCaretaker gameCaretaker = new GameCaretaker();
gameCaretaker.setGameMemento(gameRole.saveState());
// 连击100次
for (int i = 0; i < 100; i++) {
if (gameRole.fight() == -1) {
break;
}
}
gameRole.display();
// 恢复状态
System.out.println("恢复存档。。。。");
gameRole.recoveryState(gameCaretaker.getGameMemento());
gameRole.display();
}
}
总结
- 优点
- 提供了可以恢复的机制
- 实现了信息的封装,用户不需要关心状态的保存细节
- 缺点
- 会占用较多的系统存储资源