@@@模式定义:
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
这样以后就可以将该对象恢复到原先保存的状态。
@@@练习示例:
仿真系统
@@@示例代码:
\pattern\FlowAMockMemento.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; /** * 模拟运行流程A的对象的备忘录接口,是个窄接口 */ public interface FlowAMockMemento { // 空的 }
\pattern\FlowAMock.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; /** * 模拟运行流程A,只是一个示意,代指某个具体流程 */ public class FlowAMock { /** * 流程名称,不需要外部存储的状态数据 */ private String flowName; /** * 示意,代指某个中间结果,需要外部存储的结果数据 */ private int tempResult; /** * 示意,代指某个中间状态,需要外部存储的状态数据 */ private String tempState; /** * 构造方法,传入流程名称 * @param flowName 流程名称 */ public FlowAMock(String flowName) { this.flowName = flowName; } /** * 示意,运行流程的第一个阶段 */ public void runPhaseOne() { // 在这个阶段,可能产生了中间结果,示意一下 tempResult = 6; tempState = "PhaseOne"; } /** * 示意,按照方案一来运行流程后半部分 */ public void schema1() { // 示意,需要使用第一个阶段产生的数据 this.tempState += ", Schema1"; System.out.println(flowName + " " + this.tempState + " : now run " + tempResult); this.tempResult += 11; } /** * 示意,按照方案二来运行流程后半部分 */ public void schema2() { // 示意,需要使用第一个阶段产生的数据 this.tempState += ", Schema2"; System.out.println(flowName + " " + this.tempState + " : now run " + tempResult); this.tempResult += 22; } /** * 真正的备忘录对象,实现备忘录窄接口 * 实现成私有的内部类,不让外部访问 */ private static class MementoImpl implements FlowAMockMemento { /** * 示意,保存某个中间结果 */ private int tempResult; /** * 示意,保存某个中间状态 */ private String tempState; public MementoImpl(int tempResult, String tempState) { this.tempResult = tempResult; this.tempState = tempState; } public int getTempResult() { return tempResult; } public String getTempState() { return tempState; } } /** * 创建保存原发器对象状态的备忘录对象 * @return 创建好的备忘录对象 */ public FlowAMockMemento createMemento() { return new MementoImpl(this.tempResult, this.tempState); } /** * 重新设置原发器对象的状态,让其回到备忘录对象记录的状态 * @param memento 记录有原发器状态的备忘录对象 */ public void setMemento(FlowAMockMemento memento) { MementoImpl mementoImpl = (MementoImpl)memento; this.tempResult = mementoImpl.getTempResult(); this.tempState = mementoImpl.getTempState(); } }
\pattern\FlowAMementoCareTaker.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; /** * 负责保存模拟运行流程A的对象的备忘录对象 */ public class FlowAMementoCareTaker { /** * 记录被保存的备忘录对象 */ private FlowAMockMemento memento = null; /** * 保存备忘录对象 * @param memento 被保存的备忘录对象 */ public void saveMemento(FlowAMockMemento memento) { this.memento = memento; } /** * 获取被保存的备忘录对象 * @return 被保存的备忘录对象 */ public FlowAMockMemento retriveMemento() { return this.memento; } }
\user\Client.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package user; import pattern.FlowAMementoCareTaker; import pattern.FlowAMock; import pattern.FlowAMockMemento; public class Client { public static void main(String[] args) { // 创建模拟运行流程的对象 FlowAMock mock = new FlowAMock("TestFlow"); // 运行流程的第一个阶段 mock.runPhaseOne(); // 创建一个管理者 FlowAMementoCareTaker careTaker = new FlowAMementoCareTaker(); // 创建此时对象的备忘录对象,并保存到管理者对象那里,后面要用 FlowAMockMemento memento = mock.createMemento(); careTaker.saveMemento(memento); // 按照方案一来运行流程的后半部分 mock.schema1(); // 从管理者获取备忘录对象,然后设置回去 // 让模拟运行流程的对象自己恢复自己的内部状态 mock.setMemento(careTaker.retriveMemento()); // mock.setMemento(memento); // 按照方案二来运行流程的后半部分 mock.schema2(); } }
@@@模式的实现:
引入一个存储状态的备忘录对象,让它作为原发器的私有内部类。
引入一个备忘录对象的窄接口,和外部通信。
@@@模式的优点:
(1)更好的封装性;
(2)简化了原发器;
@@@模式的缺点:
可能会导致高开销;
@@@模式的本质:
保存和恢复内部状态。
@@@模式体现的设计原则:
NA