从零开始学设计模式(十七): 备忘录模式(Memento Pattern)

简介: 备忘录模式(Memento Pattern)又叫快照模式,它指的是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态。它是一种对象行为型模式。

定义


备忘录模式(Memento Pattern)又叫快照模式,它指的是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态。它是一种对象行为型模式。


上面这么说可能很难理解。 喜欢玩游戏应该都知道英雄联盟里有个英雄叫艾克,它的大招是能够逆转时间,将自己的状态和位置等返回到之前的某一个时间点的状态,我猜这里设计师可能就使用了备忘录模式,哈哈。


组成部分


备忘录模式主要有以下几个组成部分:


1、发起人类(Originator):这里主要记录当前时刻的内部状态,并且负责定义哪些是属于备份范围的状态,负责创建和恢复备忘录数据。


2、备忘录类(Memento):负责存储发起人对象的内部状态,并且在需要的时候向发起人类提供需要的内部状态。


3、管理类(Caretaker):备忘录的管理类对备忘录进行管理,保存和提供备忘录。但不能对备忘录的内容进行访问与修改。


例子


备忘录模式的例子,首先声明一个发起人类,里面主要有状态变量,还有创建备忘录和恢复备忘录的方法:


public class Originator {
    //状态
    private String state = "";
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    //创建备忘录数据方法
    public Memento create(){
        return new Memento(this.state);
    }
    //恢复备忘录数据方法
    public void restore(Memento memento) {
        this.setState(memento.getState());
    }
}
复制代码


接着声明一个备忘录类:


public 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 class Caretaker {
    private Memento memento;
    public Memento getMemento() {
        return memento;
    }
    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}
复制代码


测试方法如下:


public class MementoPatternTest {
    public static void main(String[] args) {
        Originator originator = new Originator();
        originator.setState("这是"+System.currentTimeMillis()+"的状态");
        System.out.println("初始状态:"+originator.getState());
        Caretaker caretaker = new Caretaker();
        caretaker.setMemento(originator.create());
        originator.setState("这是"+System.currentTimeMillis()+"的状态");
        System.out.println("过了一段时间后状态:"+originator.getState());
        originator.restore(caretaker.getMemento());
        System.out.println("恢复后状态:"+originator.getState());
    }
}
复制代码


运行结果:

85508f5f83e14deeb68c681091b064f0~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg

上面的例子是一个简单的单状态的备忘录模式,如果是多状态的备忘录模式可以在备忘录类中增加一个Map容器来存储所有的状态,然后在管理类中同样使用一个Map容器才存储所有的备份。比如:


class Memento {  
       private Map<String, Object> stateMap;  
       public Memento(Map<String, Object> map){  
           this.stateMap = map;  
       }  
       public Map<String, Object> getStateMap() {  
           return stateMap;  
       }  
       public void setStateMap(Map<String, Object> stateMap) {  
           this.stateMap = stateMap;  
       }  
   }
复制代码


class Caretaker {  
       private Map<String, Memento> memMap = new HashMap<String, Memento>();  
       public Memento getMemento(String index){  
           return memMap.get(index);  
       }  
       public void setMemento(String index, Memento memento){  
           this.memMap.put(index, memento);  
       }  
   }
复制代码


备忘录模式的优点


1、当发起人角色中的状态改变时,有可能这是个错误的改变,我们使用备忘录模式就可以把这个错误的改变还原。


2、备忘录模式对内部状态实现了封装。除了创建它的发起人类,其他对象都不能够访问这些状态信息。


3、发起人类不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。


备忘录模式的缺点


大多数时候使用备忘录模式都是多状态的,所以对资源的消耗是较大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。


应用场景


1、游戏或者某个程序的存档功能;


2、数据库的回滚操作;


3、一些常用的备份操作。


总结


备忘录模式可以适用于保存和恢复对象的状态, 前面的创建型设计模式中的原型模式也能保存一个对象在某一个时刻的状态,那么这里的备忘录模式和原型模式区别在哪里?原型模式保存的是当前对象的所有状态信息,所以恢复的时候生成的是和保存的对象完全一样的另外一个实例;


备忘录模式保存的则是关心的在恢复时需要的对象的部分状态信息。


最后本文以及之前的所有的设计模式中的例子代码,都将同步至github,需要的欢迎下载star。

目录
相关文章
|
2月前
|
设计模式 存储 Java
23种设计模式,备忘录模式的概念优缺点以及JAVA代码举例
【4月更文挑战第9天】备忘录模式是一种行为设计模式,它能在不破坏对象封装的前提下,捕获并保存对象的当前状态,以便后面可以恢复到这个状态。
43 0
|
20天前
|
设计模式
备忘录模式-大话设计模式
备忘录模式-大话设计模式
9 1
|
17天前
|
设计模式
设计模式-05建造者模式(Builder Pattern)
设计模式-05建造者模式(Builder Pattern)
|
2月前
|
设计模式 安全 Java
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
该文介绍了一种C++的编程技巧——奇异递归模板模式(CRTP),旨在让派生组件能继承基本组件的特定功能。通过示例展示了如何创建一个`Fighter`接口和`MmaFighter`类,其中`MmaFighter`及其子类如`MmaBantamweightFighter`和`MmaHeavyweightFighter`强制类型安全,确保相同重量级的拳手之间才能进行比赛。这种设计避免了不同重量级拳手间的错误匹配,编译时会报错。CRTP适用于处理类型冲突、参数化类方法和限制方法只对相同类型实例生效的情况。
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
|
2月前
|
存储 设计模式 安全
探索设计模式的魅力:备忘录模式揭秘-实现时光回溯、一键还原、后悔药、历史的守护者和穿越时空隧道
备忘录模式是一种行为设计模式,允许在不破坏对象封装性的情况下保存和恢复对象的内部状态。该模式通过创建备忘录对象来存储发起人的状态信息,发起人可根据需要创建和恢复备忘录。管理者则负责保存和管理备忘录,但无法访问其内容。备忘录模式简化了状态管理,支持撤销操作和历史记录功能,提高了系统的灵活性和可用性。在实际应用中,备忘录模式常用于文本编辑器、游戏和数据库事务处理等场景,确保对象状态的安全恢复和有效管理。通过备忘录模式,开发人员可以更好地控制对象状态的变化,提升软件系统的健壮性和用户体验。
37 1
探索设计模式的魅力:备忘录模式揭秘-实现时光回溯、一键还原、后悔药、历史的守护者和穿越时空隧道
|
2月前
|
设计模式 存储 Go
[设计模式 Go实现] 行为型~备忘录模式
[设计模式 Go实现] 行为型~备忘录模式
|
2月前
|
设计模式 存储 Java
Java设计模式:解释一下单例模式(Singleton Pattern)。
`Singleton Pattern`是Java中的创建型设计模式,确保类只有一个实例并提供全局访问点。它通过私有化构造函数,用静态方法返回唯一的实例。类内静态变量存储此实例,对外仅通过静态方法访问。
30 1
|
2月前
|
设计模式 存储
【设计模式系列笔记】备忘录模式
备忘录模式(Memento Pattern)是一种行为设计模式,它允许在不暴露对象实现细节的情况下捕获并恢复其内部状态。这种模式属于行为型设计模式。备忘录模式通常包含以下几个角色:发起人,备忘录,管理者。
38 0
|
2月前
|
设计模式 存储 Java
小谈设计模式(19)—备忘录模式
小谈设计模式(19)—备忘录模式
|
5天前
|
设计模式 Go
Go语言设计模式:使用Option模式简化类的初始化
在Go语言中,面对构造函数参数过多导致的复杂性问题,可以采用Option模式。Option模式通过函数选项提供灵活的配置,增强了构造函数的可读性和可扩展性。以`Foo`为例,通过定义如`WithName`、`WithAge`、`WithDB`等设置器函数,调用者可以选择性地传递所需参数,避免了记忆参数顺序和类型。这种模式提升了代码的维护性和灵活性,特别是在处理多配置场景时。
41 8