###模式定义:数据库
在不破环封装行性的前提下,捕获一个对象的内部状态,并在该对象以外保存这个状态。这样就能够将该对象恢复到原先保存的状态。 ###模式场景缓存
录入大批人员资料的时候。正在录入当前人资料时,发现上一我的录错了,此时须要恢复到上一我的的资料,进行修改。this
Word编辑时,突然断电或电脑死机,再打开时,能够看到Word提示你恢复到之前的文档。code
###模式结构 对象
Memento:备忘录。主要用来存储原发器对象的内部状态,可是具体须要存储哪些数据是由原发器对象来决定的。另外备忘录应该只能由原发器对象来访问它内部的数据,原发器外部的对象不该该能访问到备忘录对象的内部数据。接口
Originator:原发器。使用备忘录来保存某个时刻原发器自身的状态,也可使用备忘录来恢复内部状态。游戏
Caretaker:备忘录管理者,或者称为备忘录负责人。主要负责保存备忘录对象,可是不能对备忘录对象的内容进行操做或检查。事务
###代码实现 ####UML图 ####源码开发
public interface FlowAMockMemento { } public class FlowAMock { private String flowName; private int tempResult; private String tempState; public FlowAMock(String flowName) { this.flowName = flowName; } public void runPhaseOne(){ tempResult = 3; tempState = "phaseOne"; } public void schema1(){ this.tempState += ",Schema1"; System.out.println(this.tempState+":now run " + tempResult); this.tempResult += 11; } public void schema2(){ this.tempState += ",Schema2"; System.out.println(this.tempState+":now run " + tempResult); this.tempResult += 22; } public FlowAMockMemento createMemento(){ return new MementoImpl(this.tempResult,this.tempState); } public void setMemento(FlowAMockMemento memento){ MementoImpl mementoImpl = (MementoImpl) memento; this.tempResult = mementoImpl.getTempResult(); this.tempState = mementoImpl.getTempState(); } /** * 真正的备忘录对象,实现备忘录窄接口 * 实现成为私有内部类 */ private static class MementoImpl implements FlowAMockMemento{ @Getter private int tempResult; @Getter private String tempState; public MementoImpl(int tempResult, String tempState) { this.tempResult = tempResult; this.tempState = tempState; } } } @Data public class FlowAMementoCareTaker{ private FlowAMockMemento memento; } 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.setMemento(memento); mock.schema1(); mock.setMemento(memento); mock.schema2(); } }
###模式的优缺点 ####模式的优势文档
更好的封装性
备忘录模式经过使用备忘录对象,来封装原发器对象的内部状态,虽然这个对象是保存在原发器对象的外部,可是因为备忘录对象的窄接口并不提供任何方法,这样有效的保证了对原发器对象内部状态的封装,不把原发器对象的内部实现细节暴露给外部。
简化了原发器
备忘录模式中,备忘录对象被保存到原发器对象以外,让客户来管理他们请求的状态,从而让原发器对象获得简化。
窄接口和宽接口
####模式的缺点
可能会致使高开销
备忘录模式基本的功能,就是对备忘录对象的存储和恢复,它的基本实现方式就是缓存备忘录对象。这样一来,若是须要缓存的数据量很大,或者是特别频繁的建立备忘录对象,开销是很大的。
###思考
模式本质:保存和恢复内部状态
###开发中的应用场景:
棋类游戏,悔棋
普通软件,撤销操做
数据库软件中的,事务管理的,回滚操做
Photoshop软件
###相关模式
命令模式实现中,在实现命令的撤销和重作的时候,可使用备忘录模式,在命令操做的时候记录下操做先后的状态,而后在命令撤销和重作的时候,直接使用相应的备忘录对象来恢复状态就能够了。 在这种撤销的执行顺序和重作执行顺序可控的状况下,备忘录对象还能够采用增量式记录的方式,能够减小缓存的数据量。
在原发器对象建立备忘录对象的时候,若是原发器对象中所有或者大部分的状态都须要保存,一个简洁的方式就是直接克隆一个原发器对象。也就是说,这个时候备忘录对象里面存放的是一个原发器对象的实例。