備忘錄模式

大家有沒有看過尼古拉斯·凱奇主演的《Next》(中文譯名爲《預見未來》)?尼古拉斯
·凱奇飾演一個可以預視並且扭轉未來的人,其中有一個情節很是讓人心動——男女主角見
面的那段情節:Cris Johnson(尼古拉斯·凱奇飾演)坐在咖啡吧檯前,看着離自己近在咫尺
的Callie Ferris(朱莉安·摩爾飾演),計劃着怎麼認識這個命中註定的女人,看Cris Johnson
如何利用自己的特異功能:
● Cris Johnson端着一杯咖啡走過去,說“你好,可以認識你嗎?”被拒絕,恢復到坐在咖
啡吧檯前的狀態。
● 走過去詢問是否可以搭車,被拒絕,恢復原狀。
● 幫助解決困境,被拒絕,恢復原狀。
● 採用嬉皮士的方式解決困境,被拒絕,恢復原狀。
● 幫助解決困境,被打傷,裝可憐,Callie Ferris憐惜,於是乎相識了。
看看這是一件多麼幸福的事情,追求一個女生可以多次反覆地實驗,直到找到好的方法
和途徑爲止,這估計是大多數男生都希望獲得的特異功能。想想看,看到一個心儀的女生,
我們若反覆嘗試,總會有一個方法打動她的,多美好的一件事。現在我們還得回到現實生
活,我們來分析一下類似事情的經過:
● 複製一個當前狀態,保留下來,這個狀態就是等會兒搭訕女孩子失敗後要恢復的狀
態,你不恢復原始狀態,這不就露餡兒了嗎?
● 每次試探性嘗試失敗後,都必須恢復到這個原始狀態。

● N次試探總有一次成功吧,成功以後即可走成功路線。
想想看,我們這裏的場景中最重要的是哪一塊?對的,是原始狀態的保留和恢復這塊,
如何保留一個原始,如何恢復一個原始狀態纔是最重要的,那想想看,我們應該怎麼實現
呢?很簡單呀,我們可以定義一箇中間變量,保留這個原始狀態。我們先看看類圖,如圖

package MementoP;

public class Boy {
    private String state = "";
    public void changeState(){
        this.state = "bad";

    }
    public String getState(){
        return state;
    }
    public void setState(String state){
        this.state = state;
    }
}
package MementoP;

public class Client {
    public static void main(String[] args) {
        Boy boy = new Boy();
        boy.setState("great");
        System.out.println(boy.getState());
        Boy backup = new Boy();
        backup.setState(boy.getState());
        boy.changeState();
        System.out.println(boy.getState());
        boy.setState(backup.getState());
        System.out.println(boy.getState());

    }
}

Boy類封裝不夠,那我們應該如何修改呢?如果在Boy類中
再增加一個方法或者其他的內部類來保存這個狀態,則對單一職責原則是一種破壞,想想看
單一職責原則是怎麼說的?一個類的職責應該是單一的,Boy類本身的職責是追求女孩子,
而保留和恢復原始狀態則應該由另外一個類來承擔,那我們把這個類取名就叫做備忘錄,這
和大家經常在桌面上貼的那個便籤是一個概念,分析到這裏我們的思路已經非常清楚了,我
們來修改一下類圖,如圖

package MementoP;

public class Memento {
    public String state = "";
    public Memento(String state){
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}
package MementoP;

public class Boy {
    private String state = "";
    public void changeState(){
        this.state = "bad";

    }
    public String getState(){
        return state;
    }
    public void setState(String state){
        this.state = state;
    }
    public Memento createMemento(){
        return new Memento(this.state);
    }
    public void restoreMemento(Memento memento){
        this.setState(memento.getState());
    }
}
package MementoP;

public class Client {
    public static void main(String[] args) {
        /*Boy boy = new Boy();
        boy.setState("great");
        System.out.println(boy.getState());
        Boy backup = new Boy();
        backup.setState(boy.getState());
        boy.changeState();
        System.out.println(boy.getState());
        boy.setState(backup.getState());
        System.out.println(boy.getState());*/
        //聲明出主角
        Boy boy = new Boy();
//初始化當前狀態
        boy.setState("心情很棒!");
        System.out.println("=====男孩現在的狀態======");
        System.out.println(boy.getState());
//需要記錄下當前狀態呀
        Memento mem = boy.createMemento();
//男孩去追女孩,狀態改變
        boy.changeState();
        System.out.println("\n=====男孩追女孩子後的狀態======");
        System.out.println(boy.getState());
//追女孩失敗,恢復原狀
        boy.restoreMemento(mem);
        System.out.println("\n=====男孩恢復後的狀態======");
        System.out.println(boy.getState());

    }
}

備忘錄模式(Memento Pattern)提供了一種彌補真實世界缺陷的方法,讓“後悔藥”在程
序的世界中真實可行,其定義如下:
Without violating encapsulation,capture and externalize an object's internal state so that the
object can be restored to this state later.(在不破壞封裝性的前提下,捕獲一個對象的內部狀
態,並在該對象之外保存這個狀態。這樣以後就可將該對象恢復到原先保存的狀態。)

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章