首页 > 代码库 > 设计模式学习笔记--备忘录(Mamento)模式
设计模式学习笔记--备忘录(Mamento)模式
写在模式学习之前
什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式;每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案;当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式。
设计模式就是抽象出来的东西,它不是学出来的,是用出来的;或许你根本不知道任何模式,不考虑任何模式,却写着最优秀的代码,即使以“模式专家”的角度来看,都是最佳的设计,不得不说是“最佳的模式实践”,这是因为你积累了很多的实践经验,知道“在什么场合代码应该怎么写”,这本身就是设计模式。
有人说:“水平没到,学也白学,水平到了,无师自通”。诚然,模式背熟,依然可能写不出好代码,更别说设计出好框架;OOP理解及实践经验到达一定水平,同时也意味着总结了很多好的设计经验,但"无师自通",却也未必尽然,或者可以说,恰恰是在水平和经验的基础上,到了该系统的学习一下“模式”的时候了,学习一下专家总结的结果,印证一下自己的不足,对于提高水平还是很有帮助的。
本系列的设计模式学习笔记,实际是对于《Java与模式》这本书的学习记录。
备忘录模式的定义
备忘录模式(Memento Pattern),又叫快照模式(Snapshot Pattern)或Token模式,是对象的行为模式。
备忘录对象是一个用来存储另一个对象内部状态的快照的对象。备忘录模式的用意,是在不破坏封装(enscapsolution)的条件下,将另一个对象的状态捕捉(capture)住,并外部(Externalize)化,存储起来,从来可以在将来合适的时候,把这个对象还原到存储起来的状态。
备忘录模式的结构
结构图
所涉及的角色
(1)备忘录(Memento)角色:将发起人(Originator)角色的内部状态存储起来,可以保护其状态不被发起人对象之外的任何对象读取;
(2)发起人(Originator)角色:创建一个含有当前内部状态的备忘录对象,使用备忘录对象存储其内部状态;
(3)负责人(Caretaker)角色:负责保存备忘录对象,不检查备忘录对象的内容。
从以上的职责可以看出,负载人(Caretaker)角色,仅仅是把备忘录(Memento)角色存储起来,功能微小而单一,所以很多时候,其功能也被集成到发起人(Originator)角色中,形成一种备忘录模式的变种,“自述历史”模式,这可能是备忘录模式的最流行的实现了。
记住这些模式的名字可真是麻烦,很多时候,我们可能已经在需要快照的编程场景中使用过这种模式了,可是,真的不知道是备忘录模式,是“自述历史”
代码实现
public class MementoTest { public static void main(String[] args) { Originator o = new Originator(); Caretaker c = new Caretaker(); o.setState("On"); //更改发起人状态为On System.out.println("Current State : " + o.getState()); c.setMemento(o.createMemento()); //存储快照 o.setState("Off"); //更改发起人状态为Off System.out.println("Current State : " + o.getState()); o.restoreMemento(c.getMemento()); //从快照恢复状态 System.out.println("Current State : " + o.getState()); } } 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; } } class Originator { private String state; /** * 工厂方法,返回一个新的备忘录对象 */ public Memento createMemento() { return new Memento(state); } /** * 将发起人对象恢复到备忘录对象所记录的状态 */ public void restoreMemento(Memento m) { this.state = m.getState(); } public String getState() { return state; } public void setState(String state) { this.state = state; } } class Caretaker{ private Memento memento; public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento = memento; } }
备忘录模式的优缺点
优点:
(1)有时一些发起人对象的状态信息必须保存在发起人对象以外的地方,但是必须由发起人对象自己读取。这时备忘录可以把发起人对象内部信息对其他对象屏蔽起来,从而可以恰当的保持封装的边界;
优点&缺点:
这个模式,简化了发起人(Originator)类;当然同时增加了备忘录(Memento)类和负责人(Caretaker)类;这算优点还是缺点呢?
只能是我们根据具体的场景,根据实际情况进行选择。
备忘录模式的适用场景
(1)对无状态Http协议的支持技术,比如session、cookie;
(2)一些视窗软件的配置文件,关闭时保存状态,重启打开时自动到达关闭时的状态。
设计模式学习笔记--备忘录(Mamento)模式