18、Memento 备忘录模式
例如:用于记录快照(顺势状态)、存盘
1、Memento
Memento设计模式是一种软件设计模式,用于将对象回滚到其先前状态。它是行为设计模式的一部分,与算法和对象之间的职责分配有关。
行为模式描述了处理对象或类之间的通信的模式。在恢复对象状态时,Memento设计模式具有很大的适用性。需要用户退回到先前状态的应用程序利用了记忆设计模式。
这种设计模式的目的是通过不将信息暴露在所需对象之外而不违反封装原理。在本文中,我们将讨论可以使用memento设计模式的场景,描述什么是memento设计模式,并讨论其优缺点。让我们开始吧
限制是始发者是唯一存储和从memento中检索信息的人。让我们逐一查看这些参与者,以清楚地了解所有这些含义-
1.纪念品
记忆对象存储原始对象的内部状态。
发起者可以访问memento对象,任何其他对象都不能直接与其交互。
2.发起人
发起者本身负责创建一个包含其当前内部状态快照的纪念品。
此外,它使用纪念品恢复内部状态
3.看守
看守类负责保存memento的状态快照。它维护一个状态列表,然后由始发者用来切换回该状态。您将借助memento设计模式的示例了解此类的用法。
2、示例代码
1.纪念品
memento类由状态变量组成,在我们的例子中,我们使用普通字符串表示状态。记忆类有两种方法;一个是构造函数,并返回当前状态。
package cn.design.behavior.memento;
/**
* @author lin
* @version 1.0
* @date 2020/8/2 22:13
* @Description 纪念品
*/
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
Memento保留单个快照,然后由看守对象将其保留为列表
2.发起人
发起者负责设置对象的状态,并使用setState()方法进行设置。saveStateToMemento方法返回一个新的Memento对象,其中存储了当前状态,该状态存储在CareTaker对象的memento列表中。
getStateFromMemento返回状态的当前快照。
package cn.design.behavior.memento;
/**
* @author lin
* @version 1.0
* @date 2020/8/2 22:14
* @Description TODO
*/
public class Originator {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento saveStateToMemento(){
return new Memento(state);
}
public void getStateFromMemento(Memento memento){
state=memento.getState();
}
}
3. CareTaker
看守类以memento对象的形式维护状态快照列表。从看守对象中,我们可以跳到存储的不同状态,因为它是包含完整列表的状态。get方法使用传递给它的索引返回快照。
package cn.design.behavior.memento;
import java.util.ArrayList;
import java.util.List;
/**
* @author lin
* @version 1.0
* @date 2020/8/2 22:16
* @Description TODO
*/
public class CareTaker {
private List<Memento> mementoList = new ArrayList<>();
public void add(Memento m) {
mementoList.add(m);
}
public Memento get(int index) {
return mementoList.get(index);
}
}
4.备忘录模式演示
如您所见,原始对象正在设置状态,并且记忆对象的快照已添加到由照管对象维护的列表中。为了获得当前级别,我们可以直接使用原始对象中的getState()方法。但是,看守对象是我们可以从中获取状态快照并将其反映在发起者类上的对象。
getStateFromMemento()方法获取我们要跳转的“级别”(状态),并将其设置为Originator对象的状态变量。现在,如果我们直接使用getState()方法,则可以看到我们已经从看守对象维护的列表中恢复了先前保存的状态。
package cn.design.behavior.memento;
/**
* @author lin
* @version 1.0
* @date 2020/8/2 22:18
* @Description TODO
*/
public class MementoMain {
public static void main(String[] args) {
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();
originator.setState("state-1");
originator.setState("state-2");
careTaker.add(originator.saveStateToMemento());
originator.setState("state-3");
careTaker.add(originator.saveStateToMemento()); originator.setState("state-4");
System.out.println("当前状态为:" + originator.getState()); originator.getStateFromMemento(careTaker.get(0));
System.out.println("First saved state "+ originator.getState()); originator.getStateFromMemento(careTaker.get(1));
System.out.println("Second saved state "+ originator.getState()); }
}
3、Memento类图
在Memento模式中有以下登场角色。
◆Originator (生成者)
Originator角色会在保存自己的最新状态时生成Memento角色。当把以前保存的Memento角色传递给Originator角色时,它会将自己恢复至生成该Memento角色时的状态。在示例程序中,由Gamer类扮演此角色。
◆Memento (纪念品)
Memento角色会将Originator角色的内部信息整合在- -起。在Memento角色中虽然保存了Originator角色的信息,但它不会向外部公开这些信息。Memento角色有以下两种接口( API)。
●wide interface-宽接口 ( API)
Memento角色提供的“宽接口( API)”是指所有用于获取恢复对象状态信息的方法的集合。由于宽接口(API)会暴露所有Memento角色的内部信息,因此能够使用宽接口(API)的只有Originator角色。
●narrowinterface 窄接口 ( API)
Memento角色为外部的Caretaker角色提供了“窄接口( API)"。可以通过窄接口( API )获取的Memento角色的内部信息非常有限,因此可以有效地防止信息泄露。通过对外提供以上两种接口( API),可以有效地防止对象的封装性被破坏。在示例程序中,由Memento类扮演此角色。Originator角色和Memento角色之间有着非常紧密的联系。
◆Caretaker (负责人)
当Caretaker角色想要保存当前的Originator 角色的状态时,会通知Originator角色。Originator角色在接收到通知后会生成Memento角色的实例并将其返回给Caretaker 角色。由于以后可能会用Memento实例来将Originator恢复至原来的状态,因此Caretaker角色会- -直保存Memento实例。
4、小结
使用memento设计模式的优缺点是什么?
优点:
如果封装,Memento通过避免暴露仅由始发者管理的信息来保留边界。但是,正如我们在代码示例中看到的那样,它应该存储在发起者之外。我们将其存储在看守对象中。
记忆设计模式允许我们通过看守者维护状态列表来使代码在客户端保持简单。
将保存的状态保持在关键对象之外有助于保持凝聚力。
它为实现应用程序的恢复/撤消功能提供了一种简便的方法。
缺点:
如果发起者必须复制大量信息以存储在内存中,则内存可能会导致大量使用内存。
在大多数语言(例如JavaScript)中,使用记忆设计模式并不是一个简单的主意。很难确保只有始发者才能访问纪念品的状态。
使用场景: 1、需要保存/恢复数据的相关状态场景。2、提供一个可回滚的操作。
注意事项: 1、为了符合迪米特原则,还要增加一个管理备忘录的类。2、为了节约内存,可使用原型模式+备忘录模式。
综上所述:
Memento设计模式有两个目标:
一种是保存系统关键对象的重要状态。
另一个是维护关键对象的封装。
公众号:发哥讲
这是一个稍偏基础和偏技术的公众号,甚至其中包括一些可能阅读量很低的包含代码的技术文,不知道你是不是喜欢,期待你的关注。
如果你觉得文章还不错,就请点击右上角选择发送给朋友或者转发到朋友圈~
● 扫码关注我们
据说看到好文章不推荐的人,服务器容易宕机!
本文版权归发哥讲和博客园共有,原创文章,未经允许不得转载,否则保留追究法律责任的权利。
最新文章
- 【iBeacon】iBeacon前沿初探技术备忘
- oracle 32位导64位
- Kubernetes如何使用kube-dns实现服务发现
- scala 学习笔记(07) 一等公民的函数
- Windows下如何枚举所有进程
- Oracle 使用小计(3)
- Android 并行自动化测试系统 实现总结
- 设计模式之——单例模式(Singleton)的常见应用场景
- sql删除语句
- 关于android在Service中弹出Dialog对话框
- Apache benchmark对网站进行压力测试
- Helpers\Sessions
- OFBiz之SVN下载地址
- codeforces 132C Logo Turtle(dp)
- Notification和KVO有什么不同
- 前端--关于CSS盒模型
- 构建混合应用方式之 - Azure混合连接
- 常用Atom插件列表
- JAVA WEB之Spring4.x JdbcTemplate
- tcp/ip 卷一 读书笔记(3)为什么既要有IP地址又要有MAC地址