Java設(shè)計模式----備忘錄模式

定義

在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。這樣以后就可以將該對象恢復(fù)到原先保存的狀態(tài)。

結(jié)構(gòu)

備忘錄模式
  • Originator(發(fā)起人):負(fù)責(zé)創(chuàng)建一個備忘錄Memento,用以記錄當(dāng)前時刻它的內(nèi)部狀態(tài),并可以使用備忘錄恢復(fù)內(nèi)部狀態(tài)。Originator可根據(jù)需要決定Memento存儲Originator的哪些內(nèi)部狀態(tài)。
  • Memetno(備忘錄):負(fù)責(zé)存儲Originator對象的內(nèi)部狀態(tài),并可防止Originator以外的其他對象訪問備忘錄Memento。備忘錄有兩個接口,Caretaker只能看到備忘錄的窄接口,它只能將備忘錄傳遞給其他對象。Originator能夠看到一個寬接口,允許它訪問回到先前狀態(tài)所需的所有數(shù)據(jù)。
  • Caretaker(管理者):負(fù)責(zé)保存好備忘錄Memento,不能對備忘錄的內(nèi)容進(jìn)行操作或檢查。

簡單實(shí)現(xiàn)

package memento;

/**
 * 發(fā)起人
 */
public class Emp {
    private String name;
    private int age;
    private double salary;

    // 進(jìn)行備份操作,返回備忘錄對象
    public EmpMemento memento(){
        return new EmpMemento(this);
    }

    // 進(jìn)行恢復(fù)操作
    public void recovery(EmpMemento empMemento){
        this.name = empMemento.getName();
        this.age = empMemento.getAge();
        this.salary = empMemento.getSalary();
    }

    public Emp(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

/**
 * 備忘錄
 */
public class EmpMemento {
    private String name;
    private int age;
    private double salary;

    public EmpMemento(Emp e) {
        this.name = e.getName();
        this.age = e.getAge();
        this.salary = e.getSalary();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

/**
 * 管理者
 */
public class CareTaker {
    private EmpMemento empMemento;
//    private List<EmpMemento> list = new ArrayList<EmpMemento>();    // 如果需要存儲多個備份,可以使用集合

    public EmpMemento getEmpMemento() {
        return empMemento;
    }

    public void setEmpMemento(EmpMemento empMemento) {
        this.empMemento = empMemento;
    }
}
package memento;

public class Client {
    public static void main(String[] args) {
        CareTaker taker = new CareTaker();

        Emp emp = new Emp("張三",20,2000);
        System.out.println("1.姓名:"+emp.getName()+";  年齡:"+emp.getAge()+";  薪水:"+emp.getSalary());

        taker.setEmpMemento(emp.memento());     // 備份
        emp.setName("李四");
        emp.setAge(30);
        emp.setSalary(6000);
        System.out.println("2.姓名:"+emp.getName()+";  年齡:"+emp.getAge()+";  薪水:"+emp.getSalary());

        emp.recovery(taker.getEmpMemento());      // 恢復(fù)
        System.out.println("3.姓名:"+emp.getName()+";  年齡:"+emp.getAge()+";  薪水:"+emp.getSalary());
    }
}

輸出:
1.姓名:張三;  年齡:20;  薪水:2000.0
2.姓名:李四;  年齡:30;  薪水:6000.0
3.姓名:張三;  年齡:20;  薪水:2000.0

備忘點(diǎn)較多時

  • 將備忘錄壓入棧
  • 將多個備忘錄對象,序列化和持久化

小結(jié)

備忘錄模式比較適用于功能比較復(fù)雜的,但需要維護(hù)或記錄屬性歷史的類,或者需要保存的屬性只是眾多屬性中的一小部分時,Originator可以根據(jù)保存的Memento信息還原到前一狀態(tài)。如果在某個系統(tǒng)中使用命令模式時,需要實(shí)現(xiàn)命令的撤銷功能,那么命令模式可以使用備忘錄模式來存儲可撤銷操作的狀態(tài)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容