个人学习笔记分享,当前能力有限,请勿贬低,菜鸟互学,大佬绕道
如有勘误,欢迎指出和讨论,本文后期也会进行修正和补充
前言
常说,”世上没有后悔药“,现实中的确如此,但在计算机应用中,我们大量提供了”后悔“的机会,以防我们需要弥补自己的”过失“
比如,游戏玩家非常熟悉的“存档”功能(SL大法好),编辑器的撤销/重做功能功能,数据库与操作系统的备份功能等等
比如前两天,字节的某老哥删掉了公司的全部1GB以下模型,如果不能恢复数据,恐怕我们讨论的就不只是去留问题了。。。
即,保存一个对象的某个状态,以便在适当的时候恢复对象。
我们将其称为备忘录模式,又称为快照模式
1.介绍
适用目的:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
主要解决:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。
何时使用:需要记录一个对象的内部状态,允许用户取消不确定或者错误的操作,并恢复到他原先的状态
如何解决:通过一个备忘录类专门存储对象状态。
关键代码:客户不与备忘录类耦合,与备忘录管理类耦合。
应用实例:游戏存档;编辑器的撤销/重做;windows系统和浏览器的前进/后退;数据库的事务管理;数据库和操作系统的备份;
优点:
- 给用户提供了一种可以恢复状态的机制,使用户能够比较方便地回到某个历史的状态。
- 实现了信息的封装,使得用户不需要关心状态的保存细节。
- 简化了发起人。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。
缺点:资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。
使用场景:
- 需要保存/恢复数据的相关状态的场景
- 需要回滚操作的场景
- 需要复制某个状态的场景
2.结构
备忘录模式主要包括以下角色
- 发起人(Originator):记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
- 备忘录(Memento):负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
- 管理者(Caretaker):对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
3.实现步骤
-
创建 Memento 类。
//备忘录 class Memento { private String state; public Memento(String state) { this.state = state; } public String getState() { return state; } }
备忘录为只读,不允许修改
-
创建 Originator 类。
//发起人 class Originator { private String state; public void setState(String state) { this.state = state; } public String getState() { return state; } public Memento saveMemento() { return new Memento(state); } public void restoreMemento(Memento m) { this.setState(m.getState()); } }
提供对当前状态的查询和修改功能,并提供新增备忘录功能
-
创建 CareTaker 类。
//管理者 class Caretaker { private Deque<Memento> mementos = new ArrayDeque<>(); public void setMemento(Memento m) { mementos.push(m); } public Memento getMemento() { return mementos.pop(); } }
测试类
public static void main(String[] args) {
Originator or = new Originator();
Caretaker cr = new Caretaker();
or.setState("S0");
System.out.println("初始状态:" + or.getState());
cr.setMemento(or.saveMemento()); //保存状态
or.setState("S1");
System.out.println("新的状态:" + or.getState());
or.restoreMemento(cr.getMemento()); //恢复状态
System.out.println("恢复状态:" + or.getState());
}
运行结果
后记
实际开发中,备忘录模式出现的并不多,因此也没有什么案例和变型好讲。。。。
作者:Echo_Ye
WX:Echo_YeZ
Email :echo_yezi@qq.com
个人站点:在搭了在搭了。。。(右键 - 新建文件夹)