当前位置: 首页 > news >正文

设计模式-备忘录模式(Memento)

设计模式-备忘录模式(Memento)

    • 一、备忘录模式概述
      • 1.1 什么是备忘录模式
      • 1.2 简单实现备忘录模式
      • 1.3 使用备忘录模式的注意事项
    • 二、备忘录模式的用途
    • 三、备忘录模式实现方式
      • 3.1 基于数组的备忘录实现方式
      • 3.2 基于集合的备忘录实现方式
      • 3.3 基于HashMap的备忘录实现方式
      • 3.4 基于序列化的备忘录实现方式

一、备忘录模式概述

1.1 什么是备忘录模式

备忘录模式(Memento Pattern)是一种行为型设计模式,它允许你捕获对象的内部状态,并在需要时恢复该状态,而无需暴露该对象的实现细节。所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样,以后就可以将该对象恢复到原先保存的状态。

这种模式的名字可能对一些人来说稍微有点陌生,但其另一个名字快照模式可能会让人觉得更为熟悉。备忘录模式的适用场景包括:需要保存和恢复数据的场景,例如,编辑文档时需要撤销操作;需要避免重复计算的场景,例如,斐波那契数列;以及需要将一个对象的状态作为参数传递给其他对象的场景,例如,从数据库中查询数据。

1.2 简单实现备忘录模式

备忘录模式是一种行为型设计模式,它允许在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样,以后就可以将该对象恢复到原先保存的状态。

下面是一个简单的Java实现备忘录模式的例子:

首先,我们创建一个原始类(Originator):

public class Originator {private String state;public void setState(String state) {this.state = state;}public String getState() {return state;}public Memento saveStateToMemento() {return new Memento(state);}public void getStateFromMemento(Memento memento) {state = memento.getState();}
}

然后,我们创建一个备忘录类(Memento):

public class Memento {private String state;public Memento(String state) {this.state = state;}public String getState() {return state;}
}

接下来,我们创建一个负责管理备忘录的类(Caretaker):

import java.util.ArrayList;
import java.util.List;public class Caretaker {private List<Memento> mementoList = new ArrayList<>();public void add(Memento state) {mementoList.add(state);}public Memento get(int index) {return mementoList.get(index);}
}

最后,我们在主函数中测试备忘录模式:

public class Main {public static void main(String[] args) {Originator originator = new Originator();Caretaker caretaker = new Caretaker();originator.setState("状态1");caretaker.add(originator.saveStateToMemento());originator.setState("状态2");caretaker.add(originator.saveStateToMemento());originator.setState("状态3");caretaker.add(originator.saveStateToMemento());System.out.println("当前状态: " + originator.getState());originator.getStateFromMemento(caretaker.get(0));System.out.println("恢复后的状态: " + originator.getState());}
}

运行结果:

当前状态: 状态3
恢复后的状态: 状态1

1.3 使用备忘录模式的注意事项

  • 1、备忘录的保存和使用必须在同一个上下文中,不能将备忘录传递给其他对象。如果需要传递备忘录,可以使用Caretaker类来管理备忘录。

  • 2、备忘录对象需要保存原始对象的内部状态,因此备忘录对象应该与原始对象具有相同的属性和方法。但是,备忘录对象不应该包含任何业务逻辑或行为。

  • 3、如果原始对象的内部状态被修改,备忘录对象也需要相应地更新。因此,在保存备忘录之前,需要先调用原始对象的saveStateToMemento()方法。

  • 4、如果需要恢复原始对象的内部状态,可以使用getStateFromMemento()方法。但是,需要注意的是,恢复后的状态可能不是最新的状态,因为原始对象可能在恢复状态之后又进行了修改。

  • 5、备忘录模式适用于那些需要保存和恢复状态的场景,但不适用于所有场景。如果只需要保存和恢复单个状态,可以使用简单变量来实现;如果需要保存和恢复多个状态,可以使用数据结构(如数组或列表)来管理备忘录对象。

二、备忘录模式的用途

  • 1、备忘录模式主要用于保存和恢复对象的状态,以便在需要时可以恢复到先前的状态。这种模式通常用于以下情况:

  • 2、撤销操作:当一个操作序列可以被撤销时,可以使用备忘录模式来保存每个操作的结果,以便在需要时进行撤销。

  • 3、跨层传递参数:当一个对象需要将其状态传递给另一个对象时,可以使用备忘录模式将该对象的状态保存在一个备忘录中,然后将备忘录传递给另一个对象。

  • 4、避免重复计算:当一个对象的计算成本很高时,可以使用备忘录模式来保存其中间结果,以便在需要时可以直接使用这些结果,而不必重新计算它们。

  • 5、测试和维护:当需要对一个对象进行单元测试或维护时,可以使用备忘录模式来保存其当前状态,以便在测试或维护完成后可以恢复到先前的状态。

三、备忘录模式实现方式

3.1 基于数组的备忘录实现方式

基于数组的备忘录实现方式可以通过以下步骤完成:

创建一个类,该类包含一个用于保存状态的数组。
在类中定义一个方法,该方法将对象的状态保存到数组中。
在类中定义另一个方法,该方法从数组中恢复对象的状态。
在需要保存和恢复状态的地方调用相应的方法。
以下是一个简单的示例代码:

public class Memento {private int[] state;public Memento(int[] state) {this.state = state;}public int[] getState() {return state;}
}public class Originator {private int[] state;public void setState(int[] state) {this.state = state;}public int[] getState() {return state;}public Memento saveStateToMemento() {return new Memento(state);}public void getStateFromMemento(Memento memento) {state = memento.getState();}
}public class Caretaker {private List<Memento> mementos = new ArrayList<>();public void add(Memento state) {mementos.add(state);}public Memento get(int index) {return mementos.get(index);}
}public class Main {public static void main(String[] args) {Originator originator = new Originator();Caretaker caretaker = new Caretaker();originator.setState(new int[]{1, 2, 3});caretaker.add(originator.saveStateToMemento());originator.setState(new int[]{4, 5, 6});caretaker.add(originator.saveStateToMemento());originator.getStateFromMemento(caretaker.get(0)); // 恢复到第一个状态System.out.println(Arrays.toString(originator.getState())); // 输出 [1, 2, 3]}
}

在这个示例中,我们创建了一个Originator类来表示原始对象,一个Memento类来表示备忘录,一个Caretaker类来管理备忘录。在Main类的main方法中,我们创建了Originator和Caretaker对象,并使用它们来保存和恢复对象的状态。

3.2 基于集合的备忘录实现方式

基于集合的备忘录实现方式可以通过以下步骤完成:

创建一个类,该类包含一个用于保存状态的集合。
在类中定义一个方法,该方法将对象的状态添加到集合中。
在类中定义另一个方法,该方法从集合中恢复对象的状态。
在需要保存和恢复状态的地方调用相应的方法。
以下是一个简单的示例代码:

import java.util.ArrayList;
import java.util.List;public class Memento {private List<String> state;public Memento() {state = new ArrayList<>();}public void addState(String state) {this.state.add(state);}public String getState(int index) {return state.get(index);}
}public class Originator {private List<String> states;public Originator() {states = new ArrayList<>();}public void setState(String state) {states.add(state);}public String getState() {return states.get(states.size() - 1);}public Memento saveStateToMemento() {Memento memento = new Memento();memento.addState(getState());return memento;}public void getStateFromMemento(Memento memento) {int index = states.size() - 1;setState(memento.getState(index));}
}public class Caretaker {private List<Memento> mementos;public Caretaker() {mementos = new ArrayList<>();}public void add(Memento memento) {mementos.add(memento);}public Memento get(int index) {return mementos.get(index);}
}public class Main {public static void main(String[] args) {Originator originator = new Originator();Caretaker caretaker = new Caretaker();originator.setState("状态1");caretaker.add(originator.saveStateToMemento());originator.setState("状态2");caretaker.add(originator.saveStateToMemento());originator.getStateFromMemento(caretaker.get(0)); // 恢复到第一个状态System.out.println(originator.getState()); // 输出 "状态1"}
}

在这个示例中,我们创建了一个Memento类来表示备忘录,一个Originator类来表示原始对象,一个Caretaker类来管理备忘录。在Main类的main方法中,我们创建了Originator和Caretaker对象,并使用它们来保存和恢复对象的状态。

3.3 基于HashMap的备忘录实现方式

基于HashMap的备忘录实现方式可以通过以下步骤完成:

创建一个类,该类包含一个用于保存状态的HashMap。
在类中定义一个方法,该方法将对象的状态添加到HashMap中。
在类中定义另一个方法,该方法从HashMap中恢复对象的状态。
在需要保存和恢复状态的地方调用相应的方法。
以下是一个简单的示例代码:

import java.util.HashMap;public class Memento {private HashMap<String, Object> stateMap;public Memento() {stateMap = new HashMap<>();}public void addState(String key, Object value) {stateMap.put(key, value);}public Object getState(String key) {return stateMap.get(key);}
}public class Originator {private String state;public void setState(String state) {this.state = state;}public String getState() {return state;}public Memento saveStateToMemento() {Memento memento = new Memento();memento.addState("state", state);return memento;}public void getStateFromMemento(Memento memento) {state = (String) memento.getState("state");}
}public class Caretaker {private ArrayList<Memento> mementoList;public Caretaker() {mementoList = new ArrayList<>();}public void addMemento(Memento memento) {mementoList.add(memento);}public Memento getMemento(int index) {return mementoList.get(index);}
}public class Main {public static void main(String[] args) {Originator originator = new Originator();Caretaker caretaker = new Caretaker();originator.setState("状态1");caretaker.addMemento(originator.saveStateToMemento());originator.setState("状态2");caretaker.addMemento(originator.saveStateToMemento());originator.setState((String) caretaker.getMemento(0).getState("state"));System.out.println("恢复后的状态: " + originator.getState()); // 输出 "恢复后的状态: 状态1"}
}

在这个示例中,我们创建了一个Memento类来表示备忘录,一个Originator类来表示原始对象,一个Caretaker类来管理备忘录。在Main类的main方法中,我们创建了Originator和Caretaker对象,并使用它们来保存和恢复对象的状态。

3.4 基于序列化的备忘录实现方式

基于序列化的备忘录实现方式可以通过以下步骤完成:

创建一个类,该类包含一个用于保存状态的私有成员变量。
为该类添加一个构造函数,用于初始化私有成员变量。
为该类添加一个序列化方法,用于将对象的状态保存到文件中。
为该类添加一个反序列化方法,用于从文件中恢复对象的状态。
在需要保存和恢复状态的地方调用相应的序列化和反序列化方法。
以下是一个简单的示例代码:

import java.io.*;class Memento implements Serializable {private String state;public Memento(String state) {this.state = state;}public String getState() {return state;}public void setState(String state) {this.state = state;}public void saveToFile(String fileName) {try {FileOutputStream fos = new FileOutputStream(fileName);ObjectOutputStream oos = new ObjectOutputStream(fos);oos.writeObject(this);oos.close();fos.close();} catch (IOException e) {e.printStackTrace();}}public static Memento restoreFromFile(String fileName) {Memento memento = null;try {FileInputStream fis = new FileInputStream(fileName);ObjectInputStream ois = new ObjectInputStream(fis);memento = (Memento) ois.readObject();ois.close();fis.close();} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}return memento;}
}public class Main {public static void main(String[] args) {Memento memento = new Memento("初始状态");System.out.println("当前状态: " + memento.getState());memento.setState("修改后的状态");System.out.println("修改后的状态: " + memento.getState());memento.saveToFile("memento.ser");Memento restoredMemento = Memento.restoreFromFile("memento.ser");System.out.println("恢复后的状态: " + restoredMemento.getState());}
}

在这个示例中,我们创建了一个名为Memento的类,它实现了Serializable接口。我们为这个类添加了一个私有成员变量state,以及一个构造函数、一个获取状态的方法、一个设置状态的方法、一个保存状态到文件的方法和一个从文件恢复状态的方法。在main方法中,我们创建了一个Memento对象,修改了它的状态,然后将它的状态保存到文件中。接着,我们从文件中恢复了这个对象的状态,并打印出来。

http://www.lryc.cn/news/228932.html

相关文章:

  • 【机器学习】正则化到底是什么?
  • Rust5.2 Generic Types, Traits, and Lifetimes
  • c 实用化的摄像头生成avi视频程序(加入精确的时间控制)
  • Web后端开发_01
  • 二十、泛型(6)
  • Java18新增特性
  • springboot容器
  • Windows 10 下使用Visual Studio 2017 编译CEF SDK
  • 数字货币swap交易所逻辑系统开发分析方案
  • spring boot中使用Bean Validation做优雅的参数校验
  • 搜索引擎项目
  • 7.外部存储器,Cache,虚拟存储器
  • UITableView的style是UITableViewStyleGrouped
  • Java17新增特性
  • VR全景技术在城市园区发展中有哪些应用与帮助
  • 在 SQL 中,当复合主键成为外键时应该如何被其它表引用
  • Ps:通过显示大小了解图像的打印尺寸
  • Linux - 驱动开发 - watchdog - SMP机制下多核确活
  • 概念解析 | LoRA:低秩矩阵分解在神经网络微调中的魔力
  • 量子计算和量子通信技术:引领潜力无限的未来
  • nodejs+vue+python+PHP+微信小程序-安卓- 电影在线订票系统的设计与实现-计算机毕业设计推荐
  • LightDB23.4支持mysql aes_encrypt/aes_decrypt/hex/unhex函数
  • uniapp——项目day04
  • 7-爬虫-中间件和下载中间件(加代理,加请求头,加cookie)、scrapy集成selenium、源码去重规则(布隆过滤器)、分布式爬虫
  • 创建自己的nas服务,从远端拉取所需文件
  • 智慧化城市内涝的预警,万宾科技内涝积水监测仪
  • 7-18 调用一个函数
  • VB.net TCP服务端监听端口接收客户端RFID网络读卡器上传的读卡数据
  • Springboot 集成 MongoDB
  • AM@定积分的定义求某些类型的极限