设计模式轻松学【二三】备忘录模式

简介: 我们在下棋的时候,如果需要悔棋的功能,就需要系统记住每一步下棋的操作,这样才能够实现悔棋

定义与特点

  • 定义:在不破坏封装性的前提下捕获一个对象内部的状态,并在对象之外保存这个状态,以便对象以后恢复到这一状态。备忘录模式可以使系统恢复到某一历史时期的状态,又称快照模式
  • 参与角色

    • Originator(发起人):一个普通类,可以创建一个备忘录,提供存储当前内部状态和恢复内部状态的功能,它可以访问备忘录中的所有信息。
    • Memento(备忘录):存储发起人的内部状态,根据发起人来决定保存哪些内部状态,在需要的时候提供这些状态给发起人。需要注意的是,除了发起人本身与负责人类之外,备忘录对象不能直接供其他类使用。
    • Caretaker(负责人):负责人又称为管理者,它负责保存备忘录。可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。
  • 类结构图

    image.png

  • 结构代码示例

    • 定义备忘录

      //备忘录
      class Memento {
          private String state;
      
          public Memento(String state) {
              this.state = state;
          }
      
          public void setState(String state) {
              this.state = state;
          }
      
          public String getState() {
              return state;
          }
      }
    • 定义发起人

      //发起人
      class Originator {
          private String state;
      
          public void setState(String state) {
              this.state = state;
          }
      
          public String getState() {
              return state;
          }
      
          public Memento createMemento() {
              return new Memento(state);
          }
      
          public void restoreMemento(Memento m) {
              this.setState(m.getState());
          }
      }
    • 定义管理者

      //管理者
      class Caretaker {
          private Memento memento;
      
          public void setMemento(Memento m) {
              memento = m;
          }
      
          public Memento getMemento() {
              return memento;
          }
      }
    • 调用测试程序

      public class MementoTest {
      
          public static void main(String[] args) {
              Originator or = new Originator();
              or.setState("S0");
              System.out.println("初始状态:" + or.getState());
              
              Caretaker cr = new Caretaker();
              cr.setMemento(or.createMemento()); // 保存状态
              
              or.setState("S1");
              System.out.println("新的状态:" + or.getState());
              
              or.restoreMemento(cr.getMemento()); // 恢复状态
              System.out.println("恢复状态:" + or.getState());
          }
      }
      //输出结果
      初始状态:S0
      新的状态:S1
      恢复状态:S0

案例分析

以电脑文件备份还原为例,这里涉及到:文件(被备份对象)、电脑(发起备份人)、备份位置(Disk硬盘)

  • 定义被备份对象

    class MyFile {
        
        private String fileName;
        private String fileType;
        
        public MyFile(String fileName, String fileType) {
            this.fileName = fileName;
            this.fileType = fileType;
        }
        
        //省略getter&setter.....
        
        @Override
        public String toString() {
            return "MyFile [fileName=" + fileName + ", fileType=" + fileType + "]";
        }
        
    }
  • 定义备忘录

    class FileMemento {
        private MyFile myFile;
    
        public FileMemento(MyFile myFile) {
            this.myFile = myFile;
        }
    
        public MyFile getMyFile() {
            return myFile;
        }
    
        public void setMyFile(MyFile myFile) {
            this.myFile = myFile;
        }
    }
  • 定义发起人

    class Windows {
        private MyFile myFile;
    
        public MyFile getMyFile() {
            return myFile;
        }
    
        public void setMyFile(MyFile myFile) {
            this.myFile = myFile;
        }
    
        public FileMemento createMemento() {
            return new FileMemento(myFile);
        }
        
        public void restoreMemento(FileMemento fileMemento) {
            this.setMyFile(fileMemento.getMyFile());
        }
    }
  • 定义管理者

    class DiskF {
        private FileMemento fileMemento;
    
        public void setFileMemento(FileMemento fileMemento) {
            this.fileMemento = fileMemento;
        }
    
        public FileMemento getFileMemento() {
            return fileMemento;
        }
    }
  • 调用客户端

    public class MementoTest {
    
        public static void main(String[] args) {
            MyFile myFile = new MyFile("天龙八部","mp4");
            MyFile myFile2 = new MyFile("天龙八部bak","mp4");
            
            Windows windows = new Windows();
            windows.setMyFile(myFile);
            System.out.println("初始状态:" + windows.getMyFile());
            
            DiskF disk = new DiskF();
            disk.setFileMemento(windows.createMemento()); // 保存状态
            
            windows.setMyFile(myFile2);
            System.out.println("新的状态:" + windows.getMyFile());
            
            windows.restoreMemento(disk.getFileMemento()); // 恢复状态
            System.out.println("恢复状态:" + windows.getMyFile());
        }
    }
    
    //执行结果
    初始状态:MyFile [fileName=天龙八部, fileType=mp4]
    新的状态:MyFile [fileName=天龙八部bak, fileType=mp4]
    恢复状态:MyFile [fileName=天龙八部, fileType=mp4]
  • 如果需要备份多次,则需要将FileMemento单类改为List或Map集合复杂类型,确定好下标(序号)或备份标签(key)方恢复到指定的版本。

总结

  1. 优点

    • 提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
    • 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
    • 简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则
  2. 缺点

    实现复杂,如果需要维护多个备份,可能会影响系统的性能。

  3. 适用场景

    • 需要保存和恢复数据的相关状态场景。
    • 提供一个可回滚(rollback)的功能场景。
    • 需要监控的副本场景。
目录
相关文章
|
6月前
|
设计模式 存储 Java
23种设计模式,备忘录模式的概念优缺点以及JAVA代码举例
【4月更文挑战第9天】备忘录模式是一种行为设计模式,它能在不破坏对象封装的前提下,捕获并保存对象的当前状态,以便后面可以恢复到这个状态。
81 0
|
6月前
|
设计模式 存储 Java
【设计模式】备忘录模式
【设计模式】备忘录模式
|
6月前
|
设计模式 存储 Java
浅谈设计模式 - 备忘录模式(十五)
浅谈设计模式 - 备忘录模式(十五)
46 0
|
6月前
|
设计模式 存储 Java
Java设计模式【十九】:备忘录模式
Java设计模式【十九】:备忘录模式
39 0
|
2月前
|
存储 设计模式 安全
Java设计模式-备忘录模式(23)
Java设计模式-备忘录模式(23)
|
3月前
|
设计模式 算法
设计模式的基础问题之备忘录模式在软件开发的问题如何解决
设计模式的基础问题之备忘录模式在软件开发的问题如何解决
|
5月前
|
设计模式
备忘录模式-大话设计模式
备忘录模式-大话设计模式
|
4月前
|
设计模式 数据处理
iLogtail设计模式问题之什么是备忘录模式
iLogtail设计模式问题之什么是备忘录模式
|
5月前
|
设计模式 存储 Java
Java设计模式之备忘录模式详解
Java设计模式之备忘录模式详解
|
6月前
|
存储 设计模式 安全
探索设计模式的魅力:备忘录模式揭秘-实现时光回溯、一键还原、后悔药、历史的守护者和穿越时空隧道
备忘录模式是一种行为设计模式,允许在不破坏对象封装性的情况下保存和恢复对象的内部状态。该模式通过创建备忘录对象来存储发起人的状态信息,发起人可根据需要创建和恢复备忘录。管理者则负责保存和管理备忘录,但无法访问其内容。备忘录模式简化了状态管理,支持撤销操作和历史记录功能,提高了系统的灵活性和可用性。在实际应用中,备忘录模式常用于文本编辑器、游戏和数据库事务处理等场景,确保对象状态的安全恢复和有效管理。通过备忘录模式,开发人员可以更好地控制对象状态的变化,提升软件系统的健壮性和用户体验。
122 1
探索设计模式的魅力:备忘录模式揭秘-实现时光回溯、一键还原、后悔药、历史的守护者和穿越时空隧道

热门文章

最新文章

  • 1
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    45
  • 2
    C++一分钟之-C++中的设计模式:单例模式
    51
  • 3
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    36
  • 4
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    59
  • 5
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    54
  • 6
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    39
  • 7
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    49
  • 8
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    102
  • 9
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    74
  • 10
    Go语言设计模式:使用Option模式简化类的初始化
    71