二十三种设计模式第二十篇--备忘录模式

备忘录模式,备忘录模式属于行为型模式。它允许在不破坏封装的情况下捕获和恢复对象的内部状态。保存一个对象的某个状态,以便在适当的时候恢复对象,该模式通过创建一个备忘录对象来保存原始对象的状态,并将其存储在一个负责管理备忘录的负责人对象中。

备忘录模式的核心组成部分包括:

发起人(Originator):负责创建备忘录对象,并在需要的时候将自身状态保存到备忘录中。

备忘录(Memento):用于存储发起人对象的内部状态。

负责人(Caretaker):负责管理备忘录对象,可以对备忘录进行保存、恢复或删除等操作。

备忘录模式的优点包括:

  1. 封装了状态保存和恢复的细节:备忘录模式将保存和恢复对象状态的逻辑封装在备忘录对象中,发起人对象无需关心其具体实现。
  2. 支持撤销操作:通过存储历史状态的备忘录对象,可以轻松实现对象的撤销操作。
  3. 简化了原发器类:发起人对象只需关注自身的核心功能,而状态保存和恢复的责任交给备忘录和负责人对象。

备忘录模式也有一些限制和适用场景:

  • 消耗内存:如果发起人对象的状态非常大或者频繁保存状态,可能会占用大量的内存空间。
  • 额外开销:备忘录模式会引入额外的对象用于保存和管理状态,可能增加系统的开销。

其应用实例:

1、浏览器回退,前进

2、数据库备份与还原

3、Git版本管理

4、棋牌游戏悔棋

  1. 编辑器当前 undo,redo.

使用场景:

1、需要保存/恢复数据的相关状态场景。

2、提供一个可回滚的操作。

java 复制代码
/**
 * 发起人(Originator)角色:
 *     记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息
 */
public class Originator {
   private String state;
 
   public void setState(String state){
      this.state = state;
   }
 
   public String getState(){
      return state;
   }

   /**
    * 生成一个备忘录对象
    * @return
    */
   public Memento saveStateToMemento(){
      //TODO:  .....将状态信息包装进去.
      return new Memento(state);
   }

   /**
    * 恢复关态
    * @param Memento
    */
   public void getStateFromMemento(Memento Memento){
      //TODO:....从memento对象取出所有的状态进行恢复.
      state = Memento.getState();
   }
}
java 复制代码
/**
 * 管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
 */
public class CareTaker {
   //TODO:也可以是一个栈来保存.
   private List<Memento> mementoList = new ArrayList<Memento>();
 
   public void add(Memento state){
      mementoList.add(state);
   }

   /**
    * 获取第几步的状态信息
    * @param index
    * @return
    */
   public Memento get(int index){
      return mementoList.get(index);
   }

   /**
    * 出栈操作
    * @return
    */
   public Memento pop(){
      Memento last=mementoList.get(      mementoList.size()-1 );
      if( last!=null ) {
         mementoList.remove(last);
      }
      return last;
   }
}
java 复制代码
/**
 * 备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
 */
public class Memento {
   //TODO:要保存的状态信息
   private String state;
 
   public Memento(String state){
      this.state = state;
   }
 
   public String getState(){
      return state;
   }  
}
java 复制代码
/**
 * 测试类
 */
public class MementoPatternDemo {
   public static void main(String[] args) {
      //创建发起人(Originator)角色: 生成要保存的备忘的对象
      Originator originator = new Originator();
      //创建管理者(Caretaker):保存的列表
      CareTaker careTaker = new CareTaker();

      //记录状态
      originator.setState("State #1");  //#1的状态没有保存
      originator.setState("State #2");
      //保存状态
      careTaker.add(   originator.saveStateToMemento());  //只保存了#2状态.
      originator.setState("State #3");
      careTaker.add(originator.saveStateToMemento());
      originator.setState("State #4");
 
      System.out.println("当前状态: " + originator.getState());  //#4

      originator.getStateFromMemento(careTaker.get(0));
      System.out.println("取保存好的第一个状态:  " + originator.getState());  // #2

      originator.getStateFromMemento(careTaker.get(1));
      System.out.println("取保存好的第二个状态: " + originator.getState());  // #3
   }
}

注意事项:

1、为了符合迪米特原则,还要增加一个管理备忘录的类。

2、为了节约内存,可使用原型模式+备忘录模式。

相关推荐
ggdpzhk30 分钟前
idea 编辑竖列:alt +shift+insert
java·ide·intellij-idea
hikktn1 小时前
Java 兼容读取WPS和Office图片,结合EasyExcel读取单元格信息
java·开发语言·wps
迪迦不喝可乐1 小时前
软考 高级 架构师 第十一章 面向对象分析 设计模式
java·设计模式
檀越剑指大厂2 小时前
【Java基础】使用Apache POI和Spring Boot实现Excel文件上传和解析功能
java·spring boot·apache
苹果酱05672 小时前
Golang的网络流量分配策略
java·spring boot·毕业设计·layui·课程设计
孑么2 小时前
GDPU Android移动应用 重点习题集
android·xml·java·okhttp·kotlin·android studio·webview
未命名冀3 小时前
微服务面试相关
java·微服务·面试
Heavydrink3 小时前
ajax与json
java·ajax·json
阿智智3 小时前
纯手工(不基于maven的pom.xml、Web容器)连接MySQL数据库的详细过程(Java Web学习笔记)
java·mysql数据库·纯手工连接
fangxiang20083 小时前
spring boot 集成 knife4j
java·spring boot