简介
又称快照模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并且该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态
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;// 攻击力增加5this.attack += 5;return 0;}/*** 防御*/public void defense() {// 血量增加1this.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();}
}
总结
- 优点
- 提供了可以恢复的机制
- 实现了信息的封装,用户不需要关心状态的保存细节
- 缺点
- 会占用较多的系统存储资源