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

概述


  • 备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原,当前很多软件都提供了撤销(Undo)操作,其中就使用了备忘录模式。
  • 定义:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
  • 又称为标记(Token)模式
  • 是一种对象行为型模式
  • 学习难度:★★☆☆☆
  • 使用频率:★★☆☆☆

优缺点


  • 优点
  • 缺点

类图


在这里插入图片描述

组成角色


  • 备忘录发起角色(Originator)
  • 备忘录角色(Memento)
  • 备忘录管理角色(Caretaker)

Code Example


备忘录发起角色(Originator)
/**
 * 备忘发起(Originator)角色:“备忘发起角色”创建一个备忘录,用以记录当前时刻它 的内部状态。在需要时使用备忘录恢复内部状态。
 * 
 * @author yanbin
 * 
 */
public class Originator {

   private String state;

   /**
    * 返回一个新的备忘录对象
    * 
    * @return
    */
   public Memento createMemento() {
      return new Memento(state);
   }

   /**
    * 将发起人恢复到备忘录对象所记载的状态
    * 
    * @param memento
    */
   public void restoreMemento(Memento memento) {
      this.state = memento.getState();
   }

   public String getState() {
      return state;
   }

   public void setState(String state) {
      this.state = state;
      System.out.println("当前状态:" + this.state);
   }

}
备忘录角色(Memento)
/**
 * 备忘录(Memento)角色:备忘录角色存储“备忘发起角色”的内部状态。“备忘发起角色”根据需要决定备忘录角色存储“备忘发起角色”的哪些内部状态。<br>
 * 为了防止“备忘发起角色”以外的其他对象访问备忘录。备忘录实际上有两个接口,“备忘录管理者角色”只能看到备忘录提供的窄接口——
 * 对于备忘录角色中存放的属性是不可见的。“备 忘发起角色”则能够看到一个宽接口——能够得到自己放入备忘录角色中属性。 <br>
 * 
 * 
 * @author yanbin
 * 
 */
public class Memento {

   private String state;

   public Memento(String state) {
      this.state = state;
   }

   public String getState() {
      return state;
   }

   public void setState(String state) {
      this.state = state;
   }

}
备忘录管理角色(Caretaker)
/**
 * 备忘录管理者(Caretaker)角色:负责保存好备忘录。不能对备忘录的内容进行操作 或检查。
 * 
 * @author yanbin
 * 
 */
public class Caretaker {

   private Memento memento;

   /**
    * 备忘录的取值方法
    * 
    * @return
    */
   public Memento retrieveMemento() {
      return this.memento;
   }

   /**
    * 备忘录的赋值方法
    * 
    * @param memento
    */
   public void saveMemento(Memento memento) {
      this.memento = memento;
   }

}
客户端
/**
 * 备忘录模式(Memento):又称标记(Token)模式。在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后
 * 就可将该对象恢复到原先保存的状态。备忘录模式是专门来存放对象历史状态的。<br>
 * 组成:备忘录(Memento)角色;备忘发起(Originator)角色;备忘录管理者(Caretaker)角色;<br>
 * 
 * Java 中可保存封装的方法:第一种就是采用两个不同的接口类来限制访问权限。,一个提供比较完
 * 备的操作状态的方法,我们称它为宽接口;而另一个则可以只是一个标示,我们称它为窄接
 * 口。这种实现比较简单,但是需要人为的进行规范约束——而这往往是没有力度的。
 * 
 * 第二种方法便很好的解决了第一种的缺陷:采用内部类来控制访问权限。将备忘录角色 作为“备忘发起角色”的一个私有内部类。
 * 
 * 第三种方式是不太推荐使用的:使用 clone 方法来简化备忘录模式
 * 
 * 适用情况:如果备份的“备忘发起角色”存在大量的信息或者创建、恢复操作非常频繁,则可能造成很大的开销。必须保存一个对象在某一个时刻的(部分)状态,
 * 这样以后需要时它才能恢复到先前的状态。如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
 * 
 * @author yanbin
 * 
 */
public class MementoPattern {

   public static void main(String[] args) {
      Originator originator = new Originator();
      Caretaker caretaker = new Caretaker();
      // 改变负责人对象的状态
      originator.setState("On");
      // 创建备忘录对象,并将发起人对象的状态储存起来
      caretaker.saveMemento(originator.createMemento());
      // 修改发起人的状态
      originator.setState("Off");
      // 恢复发起人对象的状态
      originator.restoreMemento(caretaker.retrieveMemento());

      System.out.println(originator.getState());
   }

}

猜你喜欢

转载自blog.csdn.net/yanbin0830/article/details/88869163