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

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

定义与特点

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

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