设计模式剖析系列之快照/备忘录模式

By heiry on 2019-08-23 [ in 技术 ]

快照/备忘录模式

快照模式也称为备忘录模式,其作用是将捕获对象的状态保存起来,在需要的时候可以进行恢复。

核心结构:

A.源发器 Originator类,对象的基本状态信息类,其含两个核心方法,其一是备份操作的setMemento()方法,该方法返回一个备份对象Memento实例。另一个是恢复操作的recovery(Memento m)方法,其需要传入一个已经备份的Memento实例。

B. 快照Memento类,用于创建源发器实例的快照。其属性包含了源发器所有属性。构造方法需要传入一个需要备份的源发器Originator类实例。

C. 快照管理类,用于关联已经创建的快照对象实例。

以上三者关系及客户端调用方法如下图所示:

 

备忘录模式UML类图

 

以下以风险投资公司对其投资的公司进行状态监测的实例,来说明快照模式的使用。

package net.mosang.memento;
/**
 * 源发器类:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
 * 记录XX公司某个时间点的状态
 * @author Heiry
 *
 */
public class Originator {
  private int staffNum ; //员工人数
  private double profit; //毛利润
  private String status; // 所处状态:上升期、平稳期、过渡期。。。。
  
  //备份操作
  public Memento setMemento() {
    System.out.println("对当前状态进行备份操作!");
    return new Memento(this);
  }
  
  //恢复操作
  public void recovery(Memento m) {
    this.staffNum = m.getStaffNum();
    this.profit = m.getProfit();
    this.status = m.getStatus();
  }
  
  public Originator(int staffNum, double profit, String status) {
    super();
    this.staffNum = staffNum;
    this.profit = profit;
    this.status = status;
  }
  public int getStaffNum() {
    return staffNum;
  }
  public void setStaffNum(int staffNum) {
    this.staffNum = staffNum;
  }
  public double getProfit() {
    return profit;
  }
  public void setProfit(double profit) {
    this.profit = profit;
  }
  public String getStatus() {
    return status;
  }
  public void setStatus(String status) {
    this.status = status;
  }
  
}
package net.mosang.memento;
/**
 * 备忘录类
 * @author Heiry
 *
 */

public class Memento {
  private int staffNum ; //需要保存的员工人数数据
  private double profit; //需要保存的毛利润数据
  private String status; // 需要保存的公司状态信息
  public Memento(Originator originator) {
    this.staffNum = originator.getStaffNum();
    this.profit = originator.getProfit();
    this.status = originator.getStatus();
  }
  public int getStaffNum() {
    return staffNum;
  }
  public void setStaffNum(int staffNum) {
    this.staffNum = staffNum;
  }
  public double getProfit() {
    return profit;
  }
  public void setProfit(double profit) {
    this.profit = profit;
  }
  public String getStatus() {
    return status;
  }
  public void setStatus(String status) {
    this.status = status;
  }
  
}
package net.mosang.memento;
/**
 * 管理者类:负责对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
 * 实际上是作为一个中间临时值的中转作用
 * @author Heiry
 *
 */

public class Caretaker {
  private Memento memento; //对备忘录对象做保存、中转,如果有多个备忘录状态需要保存或中转,可用集合

  public Memento getMemento() {
    return memento;
  }

  public void setMemento(Memento memento) {
    this.memento = memento;
  }
  

}
package net.mosang.memento;
/**
 * 客户端类
 * @author Heiry
 *
 */
public class Client {
  public static void main(String[] args) {
    Caretaker caretaker = new Caretaker();
    //创建XX公司某时间的状态
    Originator og1 = new Originator(100, 8000, "创业期");
    // 进行当前状态的备份
    caretaker.setMemento(og1.setMemento());
    //对当前状态做更改
    og1.setStaffNum(200);
    og1.setProfit(9000);
    og1.setStatus("平稳期");
    System.out.println("新的公司状态为:StaffNum-->"+og1.getStaffNum()+"Profit-->"+og1.getProfit()+"Status-->"+og1.getStatus());
    //对备份的状态进行恢复
    og1.recovery(caretaker.getMemento());
    System.out.println("恢复后的公司状态为:StaffNum-->"+og1.getStaffNum()+"Profit-->"+og1.getProfit()+"Status-->"+og1.getStatus());		
    
  }
}

输出结果如下:

对当前状态进行备份操作!
新的公司状态为:StaffNum-->200Profit-->9000.0Status-->平稳期
恢复后的公司状态为:StaffNum-->100Profit-->8000.0Status-->创业期

 

 >>

京ICP备15064511号 © 2009-2017 MOSANG.NET DESIGNED BY HEIRY WU