Java - GoF设计模式详解19(备忘录模式)
十九、备忘录模式
1,基本介绍
(1)备忘录模式(Memento)又称快照模式,或者令牌模式。指在不破坏封装性的前提下,将一个对象的内部状态存储在另一个对象中,这样以后就可将该对象恢复到原先保存的状态。
(2)该模式中包含的角色及其职责如下:
- 发起人角色(Originator):记录当前时刻的内部状态,可以创建和恢复备忘录。
- 备忘录角色(Memento):存储发起人的内部状态,在发起人之外不可以访问。
- 备忘录管理者角色(Caretaker):负责保存备忘录,但不能对备忘录的内容进行操作或检查。在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。
2,使用样例
(1)下面我们使用游戏中角色存档的样例演示备忘录模式的使用。通过备忘录模式来记录玩家的进度,并在玩家失败或者重启时恢复进度。首先我们创建一个发起人 Player 类,它有两个字段表示当前游戏人物的等级和当前拥有的道具,同时提供了 createState 和 restore 方法来创建和恢复备忘录。// 游戏内的人物(发起人) class Player { // 等级 private int level; // 持有道具 private List<String> items; // 创建备忘录 public PlayerState createState() { return new PlayerState(level, new ArrayList<>(items)); } // 恢复备忘录 public void restore(PlayerState state) { level = state.getLevel(); items = state.getItems(); } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } public List<String> getItems() { return items; } public void setItems(List<String> items) { this.items = items; } }
(2)接着定义一个 PlayerState 类备忘录,它有两个字段:level 表示等级,items 表示道具。
// 人物存档(备忘录) class PlayerState { //等级 private int level; // 持有道具 private List<String> items; public PlayerState(int level, List<String> items) { this.level = level; this.items = items; } public int getLevel() { return level; } public List<String> getItems() { return items; } }
(3)然后定义一个 Game 类充当管理者,它有一个字段 state 表示当前的状态。它提供了 setState 和 getState 方法来保存和恢复备忘录。
// 游戏(管理者) class Game { // 当前状态(当前持有的备忘录) private PlayerState state; public void setState(PlayerState state) { this.state = state; } public PlayerState getState() { return state; } }
(4)最后测试一下。我们创建了一个 Player 对象设置初始的等级和道具。然后创建一个备忘录保存起来。当玩家游玩了一段时间后,又可以通过备忘录恢复到之前的状态。
public class Test { public static void main(String[] args) { // 创建游戏内玩家人物对象 Player player = new Player(); // 设置初始等级与物品 player.setLevel(1); player.setItems(Arrays.asList("铁剑", "铁盾")); System.out.println("--- 初始状态 ---"); System.out.println("当前等级:" + player.getLevel()); System.out.println("持有物品:" + player.getItems()); // 创建游戏对象 Game game = new Game(); // 创建一个备忘录并保存到游戏中 game.setState(player.createState()); // 游戏过程中角色状态变更 player.setLevel(20); player.setItems(Arrays.asList("青铜剑", "青铜盾", "普通弓")); System.out.println("--- 游戏一段时间后 ---"); System.out.println("当前等级:" + player.getLevel()); System.out.println("持有物品:" + player.getItems()); // 从备忘录中恢复状态 player.restore(game.getState()); System.out.println("--- 读取存档 ---"); System.out.println("当前等级:" + player.getLevel()); System.out.println("持有物品:" + player.getItems()); } }