模式说明
以游戏中的存档和恢复存档为例,在游戏过程中需要保存当前游戏状态(包括各种游戏角色属性)作为存档,在之后的某个时刻能够恢复这个存档。文档中的撤销操作也有类似的需求。此类场景可以用备忘录模式(也叫快照模式)实现。该模式涉及三个角色,发起人类,备忘录类和备忘录管理者类。发起人类管理系统当前状态,并有一个保存为备忘的存档方法,一个恢复为指定备忘版本的恢复存档方法。备忘录类只管理该备忘的状态信息,而备忘录管理者只管理备忘录实例。符合单一职责原则。
本示例客户端中展示备忘录使用过程。声明一个发起者,该发起者设置系统状态后存档。然后创建当前系统存档(备忘录),并让一个备忘录管理者持有。接着该发起者修改系统状态,最后调用存档恢复方法恢复到修改前状态。
结构
发起人类
持有所有状态信息,并有对应的getter/setter方法。维护一个存档方法createMemento,返回记录当前系统状态信息的Memento。另有一个恢复指定存档的方法restoreMomento(Memento m),通过参数执行要恢复的Memento。
备忘录类
管理一个备忘中的系统状态信息。本例中只设置了一个状态信息String state,通过构造器初始化该state,并有该state的getter/setter。
备忘录管理者类
持有一个备忘录实例,并有该备忘录实例的getter/setter。
代码演示
package com.yukiyama.pattern.behavior;/*** 备忘录模式*/public class MementoDemo {public static void main(String[] args) {// 声明一个发起者实例Originator ori = new Originator();// 设置状态为“Alive”ori.setState("Alive");// 初始时状态为"Alive",输出"当前状态为:Alive"ori.display();// 声明一个备忘录管理者并让其持有当前mementoMementoManager manager = new MementoManager();manager.setMemento(ori.CreateMemento());// 修改ori中的状态为"Dead"ori.setState("Dead");// 此时ori中的状态为"Dead",输出"当前状态为:Dead"ori.display();// 通过管理者持有的备忘录恢复存档ori.restoreMemento(manager.getMemento());// 恢复后状态为存档时的"Alive",输出"当前状态为:Alive"ori.display();}}/*** 发起人类* 持有所有状态信息,并有对应的getter/setter方法。维护一个存档方法* createMemento,返回记录当前系统状态信息的Memento。另有一个恢复指定* 存档的方法restoreMomento(Memento m),通过参数执行要恢复的Memento。*/class Originator{private String state;public String getState() {return state;}public void setState(String state) {this.state = state;}public Memento CreateMemento() {return new Memento(state);}public void restoreMemento(Memento memento) {this.state = memento.getState();}public void display() {System.out.println("当前状态为:" + state);}}/*** 备忘录类* 管理一个备忘中的系统状态信息。本例中只设置了一个状态信息String state,* 通过构造器初始化该state,并有该state的getter/setter。*/class Memento{private String state;public Memento(String state) {this.state = state;}public String getState() {return state;}public void setState(String state) {this.state = state;}}/*** 备忘录管理者类* 持有一个备忘录实例,并有该备忘录实例的getter/setter。*/class MementoManager{private Memento memento;public Memento getMemento() {return memento;}public void setMemento(Memento memento) {this.memento = memento;}}
