参考文档:
https://www.cnblogs.com/chenssy/p/3341526.html
定义:
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
uml类图:
模式组成:
- Originator: 原发器。负责创建一个备忘录,用以记录当前对象的内部状态,通过也可以使用它来利用备忘录恢复内部状态。同时原发器还可以根据需要决定Memento存储Originator的那些内部状态。
- Memento: 备忘录。用于存储Originator的内部状态,并且可以防止Originator以外的对象访问Memento。在备忘录Memento中有两个接口,其中Caretaker只能看到备忘录中的窄接口,它只能将备忘录传递给其他对象。Originator可以看到宽接口,允许它访问返回到先前状态的所有数据。
- Caretaker: 负责人。负责保存好备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象。
优点:
- 给用户提供了一种可以恢复状态的机制。可以是用户能够比较方便地回到某个历史的状态。
- 实现了信息的封装。使得用户不需要关心状态的保存细节。
缺点:
- 会占用较多的内存,消耗资源
应用场景:
- 需要提供回滚操作的需求,使用备忘录模式非常适合,比如jdbc的事务操作,文本编辑器的Ctrl+Z恢复等。
- java.util.Date
- java.io.Serializable
备忘录模式vs克隆:
- 进行一次克隆会将对象的全部属性都复制到一个新的对象中去,而当我们仅需要备份对象中一部分属性的时候就只能使用备忘录模式。
举个栗子:
定义原发器
class Originator { private String state; public Originator(String s) { this.state = s; } public Memento createMemento() { System.out.println("备份啦备份啦,备份的进度是 " + state); return new Memento(state); } public void rollback(Memento me) { this.setState(me.getState()); } public String getState() { return state; } public void setState(String state) { this.state = state; } }
定义备忘录
class Memento { private String state; public String getState() { return state; } public void setState(String state) { this.state = state; } public Memento(String state) { this.state = state; } }
负责人调用
public static void main(String[] args) { Originator ori = new Originator("111"); System.out.println("我现在的进度是 :" + ori.getState()); Memento me = ori.createMemento(); ori.setState("222"); System.out.println("更新啦更新啦,现在的进度是 " + ori.getState()); ori.rollback(me); System.out.println("回滚啦回滚啦,现在的进度是 " + ori.getState()); }
输出