java备忘录模式实例

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

           态。

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

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;    }

}

}  

使用备忘录的潜在代价

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值