java备忘录模式实例

来源:互联网 发布:ucloud 阿里云 编辑:程序博客网 时间:2024/05/19 06:15

定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状

           态。

备忘录模式引入一个存储状态的备忘录对象,为了让外部无法访问这个对象的值,一般把这个对象实现成需要保存数据的对象的内部类,通常还是私有的,保证封装性不被破坏。但是这个备忘录对象需要存储在外部,所以要让备忘录对象实现一个窄接口,这个接口是空的,只是一个标识接口,什么方法都没有,从而保证了备忘录内的数据不会被外部获取或操作。

Java 设计模式 之 备忘录模式(Memento) - 低调的华丽 - 辉色空间

Memento:备忘录。主要用来存储原发器对象的内部状态。

Originator:原发器。需要备忘录对象保存其内部状态的对象。

Caretaker:备忘录管理者。主要是保存备忘录对象。

/**
 * 备忘录的窄接口
 *
 */
public interface Memento {

/**
 * 原发器对象
 *
 */
public class Originator {

          /**
           * 原发器的状态
           */
          private String state = "";
          /**
           * 创建原发器的备忘录对象
           * @return
           */
          public Memento createMemento(){
                    return new MementoImpl(state);
          }
          /**
           * 重新设置备忘录的对象,让他回到备忘录记录的状态
           * @param memento
           */
          public void setMemento(Memento memento){
                    MementoImpl mementoImpl = (MementoImpl)memento;
                    this.state = mementoImpl.getState();
          }
          /**
           * 真正的备忘录对象,实现备忘录窄接口
           * 实现成私有的,不让外部访问
           *
           */
          private static class MementoImpl implements Memento {

                      private String state = "";
  
                      public MementoImpl(String state){
                                this.state = state;
                      }
  
                      public String getState(){
                                return state;
                      }
        }
}

/**
 * 负责保存备忘录的对象
  *
 */
public class Caretaker {

            /**
             * 备忘录对象
             */
           private Memento memento null;
           /**
            * 保存备忘录对象
            * @param memento 要被保存的备忘录对象
            */
          public void saveMemento(Memento memento) {
                    this.memento = memento;
          }
          /**
           * 获取被保存的备忘录对象
           * @return 被保存的备忘录对象
           */
          public Memento retrieveMemento(){
                    return this.memento;
          }
}

样例

Java 设计模式 之 备忘录模式(Memento) - 低调的华丽 - 辉色空间
 

/** * 备忘录窄接口 * */public interface FlowAMockMemento {

}

/** * 原发器,模拟运行流程A * @author joe * */public class FlowAMock {

  /**  * 流程名  */  private String flowName;  /**  * 外部需要的结果数据  */  private int tempResult;  /**  * 需要外部存储的状态数据  */  private String tempState;

 

  public FlowAMock(String flowName) {   this.flowName = flowName;  }  /**  * 运行流程的第一阶段(前半部分)  */  public void runPhaseOne(){   tempResult = 3;   tempState = "PhaseOne result";  }  /**  * 按照方案一来运行流程的后半部分  */  public void schema1() {   System.out.println(this.tempState + " is " + tempResult);   this.tempResult += 11;   this.tempState = "Running Schema1 result";   System.out.println(this.tempState + " is " + tempResult);  }  /**  * 按照方案二来运行流程的后半部分  */  public void schema2(){   System.out.println(this.tempState + " is " + tempResult);   this.tempResult += 22;   this.tempState = "Running Schema2 result";   System.out.println(this.tempState + " is " + tempResult);  }  /**  * 创建原发器的备忘录对象  * @return  */  public FlowAMockMemento createMemento(){   return new MementoImpl(this.tempResult, this.tempState);  }  /**  * 重新设置原发器对象状态,让其回到备忘录对象记录的状态  * @param memento  */  public void setMemento(FlowAMockMemento memento){   MementoImpl mementoImpl = (MementoImpl)memento;   this.tempResult = mementoImpl.getTempResult();   this.tempState = mementoImpl.getTempState();  }  /**  * 真正的备忘录对象,实现备忘录的窄接口  * 实现成私有的内部类,不让外部访问  *  */  private static class MementoImpl implements FlowAMockMemento {   private int tempResult;   private String tempState;

 

   public MementoImpl(int tempResult, String tempState) {    this.tempResult = tempResult;    this.tempState = tempState;   }

   public int getTempResult() {    return tempResult;   }

   public String getTempState() {    return tempState;   }   }}

/** * 保存模拟流程A对象的备忘录对象 * */public class FlowAMementoCareTaker {

  /**  * 模拟流程A对象的备忘录对象  */  private FlowAMockMemento memento = null;  /**  * 保存备忘录对象  * @param memento  */  public void saveMemento(FlowAMockMemento memento) {   this.memento = memento;  }  /**  * 获取被保存的备忘录对象  * @return  */  public FlowAMockMemento retrieveMemento() {   return this.memento;  }}

public class Client {

  public static void main(String[] args) {   FlowAMock flowA = new FlowAMock("TestFlow");   flowA.runPhaseOne();   //创建此时的备忘录对象   FlowAMockMemento memento = flowA.createMemento();   //创建一个管理者   FlowAMementoCareTaker careTaker = new FlowAMementoCareTaker();   careTaker.saveMemento(memento);     flowA.schema1();   flowA.setMemento(careTaker.retrieveMemento());   //flowA.setMemento(memento);   flowA.schema2();  }}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

结合原型模式:如果原发器对象中全部或大部分的状态都需要保存,一个简洁的办法就是直接克隆一个原发器对象。也就是说这时备忘录对象中存放的是一个原发器对象的实例。

public class FlowAMock implements Cloneable{

  /**  * 流程名  */  private String flowName;  /**  * 外部需要的结果数据  */  private int tempResult;  /**  * 需要外部存储的状态数据  */  private String tempState;

 

  public FlowAMock(String flowName) {   this.flowName = flowName;  }   /**  * 运行流程的第一阶段(前半部分)  */  public void runPhaseOne(){   tempResult = 3;   tempState = "PhaseOne result";  }  /**  * 按照方案一来运行流程的后半部分  */  public void schema1() {   System.out.println(this.tempState + " is " + tempResult);   this.tempResult += 11;   this.tempState = "Running Schema1 result";   System.out.println(this.tempState + " is " + tempResult);  }  /**  * 按照方案二来运行流程的后半部分  */  public void schema2(){   System.out.println(this.tempState + " is " + tempResult);   this.tempResult += 22;   this.tempState = "Running Schema2 result";   System.out.println(this.tempState + " is " + tempResult);  }  public FlowAMockMemento createMemento(){   try {    return new MementoImpl((FlowAMock) this.clone());   } catch (CloneNotSupportedException e) {    e.printStackTrace();   }   return null;  }  /**  * 设置原发器对象的状态,让其回到备忘录对象记录的状态  * @param memento  */  public void setMemento(FlowAMockMemento memento) {   MementoImpl mementoImpl = (MementoImpl)memento;   this.tempResult = mementoImpl.getFlowAMock().tempResult;   this.tempState = mementoImpl.getFlowAMock().tempState;  }  private static class MementoImpl implements FlowAMockMemento{   private FlowAMock flowAMock = null;     public MementoImpl (FlowAMock flowAMock){    this.flowAMock = flowAMock;   }     public FlowAMock getFlowAMock(){    return flowAMock;   }

}

} 

使用备忘录的潜在代价

标准的备忘录模式的实现机制是依靠缓存来实现的,因此,当需要备忘录的数据较大时,或者数量很多时,或者用户频繁第创建备忘录对象时,都会导致很大的开销。

0 0
原创粉丝点击