大家有沒有看過尼古拉斯·凱奇主演的《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.(在不破壞封裝性的前提下,捕獲一個對象的內部狀
態,並在該對象之外保存這個狀態。這樣以後就可將該對象恢復到原先保存的狀態。)