備忘錄模式(Memento)
定義:
備忘錄模式:在不影響封裝的前提下,捕獲一個對象的狀态,并在該對象之外儲存此狀态,以便之後可以恢複對象到此狀态。
核心:
就是儲存某個對象内部狀态的拷貝,這樣以後就可以将該對象恢複到原先的狀态。
結構角色:
源發器類(Originator):負責建立一個備忘錄Memento,用于記錄目前時刻它的内部狀态,并可以使用備忘錄恢複内部狀态。
備忘錄類(Memento):負責存儲Originator對象的内部狀态,并可以防止Originator以外的其它對象通路備忘錄Memento。
負責人類(CareTaker):負責儲存好備忘錄Memento。
場景:
比如你正在寫部落格,部落格會自動儲存你編寫的部落格内容到草稿裡面,如果你寫着寫着電腦突然斷電或者當機了,等你重新開機之後,你可以恢複到之前部落格自動儲存的那個狀态。
案例:
備忘錄類
package com.kevin.行為型模式.備忘錄模式.memento;
/**
* @author kevin
* @version 1.0
* @description 備忘錄類
* @createDate 2019/3/4
*/
public class EmpMemento {
private String ename;
private int age;
private double salary;
public EmpMemento(Emp e) {
this.ename = e.getEname();
this.age = e.getAge();
this.salary = e.getSalary();
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
源發器類
package com.kevin.行為型模式.備忘錄模式.memento;
/**
* @author kevin
* @version 1.0
* @description 源發器類
* @createDate 2019/3/4
*/
public class Emp {
private String ename;
private int age;
private double salary;
// 進行備忘操作,并傳回備忘錄對象
public EmpMemento memento(){
return new EmpMemento(this);
}
// 進行資料恢複,恢複成指定備忘錄對象的值
public void recovery(EmpMemento mmt) {
this.ename = mmt.getEname();
this.age = mmt.getAge();
this.salary = mmt.getSalary();
}
public Emp(String ename, int age, double salary) {
this.ename = ename;
this.age = age;
this.salary = salary;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
負責人類
package com.kevin.行為型模式.備忘錄模式.memento;
import java.util.ArrayList;
import java.util.List;
/**
* @author kevin
* @version 1.0
* @description 負責人類
* 負責管理備忘錄對象
* @createDate 2019/3/4
*/
public class CareTaker {
private EmpMemento memento;
// 可以儲存多個備忘錄點
//private List<EmpMemento> list = new ArrayList<EmpMemento>();
public EmpMemento getMemento() {
return memento;
}
public void setMemento(EmpMemento memento) {
this.memento = memento;
}
}
測試備忘錄模式
package com.kevin.行為型模式.備忘錄模式.memento;
/**
* @author kevin
* @version 1.0
* @description 測試備忘錄模式
* @createDate 2019/1/18
*/
public class Test {
public static void main(String[] args) {
CareTaker taker = new CareTaker();
Emp emp = new Emp("KEVIN", 20, 10000);
System.out.println("第一次列印對象: "+ emp.getEname() + "," + emp.getAge()+"," +emp.getSalary());
// 備份資料
taker.setMemento(emp.memento());
emp.setAge(18);
emp.setEname("COCO");
emp.setSalary(9000);
System.out.println("第二次列印對象: "+ emp.getEname() + "," + emp.getAge()+"," +emp.getSalary());
emp.recovery(taker.getMemento()); // 恢複到備忘錄對象儲存的狀态
System.out.println("第三次列印對象: "+ emp.getEname() + "," + emp.getAge()+"," +emp.getSalary());
}
}
備忘錄模式的UML類圖

開發中常見的應用場景:
- 棋類遊戲中的,悔棋
- 普通軟體中的,撤銷操作
- 資料庫軟體中的,事務管理中的,復原操作
- Photoshop軟體中的,曆史記錄