摘要:原理備忘錄對(duì)象是一個(gè)用來(lái)存儲(chǔ)另外一個(gè)對(duì)象內(nèi)部狀態(tài)的快照的對(duì)象。備忘錄模式的用意是在不破壞封裝的條件下,將一個(gè)對(duì)象的狀態(tài)捕捉(Capture)住,并外部化,存儲(chǔ)起來(lái),從而可以在將來(lái)合適的時(shí)候把這個(gè)對(duì)象還原到存儲(chǔ)起來(lái)的狀態(tài)。備忘錄模式常常與命令模式和迭代子模式一同使用。組成 備忘錄模式所涉及的角色有三個(gè):備忘錄(Memento)角色、發(fā)起人(Originator)角色、負(fù)責(zé)人(Caretaker)角
原理
備忘錄對(duì)象是一個(gè)用來(lái)存儲(chǔ)另外一個(gè)對(duì)象內(nèi)部狀態(tài)的快照的對(duì)象。備忘錄模式的用意是在不破壞封裝的條件下,將一個(gè)對(duì)象的狀態(tài)捕捉(Capture)住,并外部化,存儲(chǔ)起來(lái),從而可以在將來(lái)合適的時(shí)候把這個(gè)對(duì)象還原到存儲(chǔ)起來(lái)的狀態(tài)。備忘錄模式常常與命令模式和迭代子模式一同使用。
組成
備忘錄模式所涉及的角色有三個(gè):備忘錄(Memento)角色、發(fā)起人(Originator)角色、負(fù)責(zé)人(Caretaker)角色。
備忘錄(Memento)角色又如下責(zé)任:
?。?)將發(fā)起人(Originator)對(duì)象的內(nèi)戰(zhàn)狀態(tài)存儲(chǔ)起來(lái)。備忘錄可以根據(jù)發(fā)起人對(duì)象的判斷來(lái)決定存儲(chǔ)多少發(fā)起人(Originator)對(duì)象的內(nèi)部狀態(tài)。
?。?)備忘錄可以保護(hù)其內(nèi)容不被發(fā)起人(Originator)對(duì)象之外的任何對(duì)象所讀取。
發(fā)起人(Originator)角色有如下責(zé)任:
?。?)創(chuàng)建一個(gè)含有當(dāng)前的內(nèi)部狀態(tài)的備忘錄對(duì)象。
?。?)使用備忘錄對(duì)象存儲(chǔ)其內(nèi)部狀態(tài)。
負(fù)責(zé)人(Caretaker)角色有如下責(zé)任:
?。?)負(fù)責(zé)保存?zhèn)渫泴?duì)象。
?。?)不檢查備忘錄對(duì)象的內(nèi)容。
“自述歷史”模式
所謂“自述歷史”模式(History-On-Self Pattern)實(shí)際上就是備忘錄模式的一個(gè)變種。在備忘錄模式中,發(fā)起人(Originator)角色、負(fù)責(zé)人(Caretaker)角色和備忘錄(Memento)角色都是獨(dú)立的角色。雖然在實(shí)現(xiàn)上備忘錄類可以成為發(fā)起人類的內(nèi)部成員類,但是備忘錄類仍然保持作為一個(gè)角色的獨(dú)立意義。在“自述歷史”模式里面,發(fā)起人角色自己兼任負(fù)責(zé)人角色。
“自述歷史”模式的類圖如下所示:
備忘錄角色有如下責(zé)任:
(1)將發(fā)起人(Originator)對(duì)象的內(nèi)部狀態(tài)存儲(chǔ)起來(lái)。
(2)備忘錄可以保護(hù)其內(nèi)容不被發(fā)起人(Originator)對(duì)象之外的任何對(duì)象所讀取。
發(fā)起人角色有如下責(zé)任:
?。?)創(chuàng)建一個(gè)含有它當(dāng)前的內(nèi)部狀態(tài)的備忘錄對(duì)象。
(2)使用備忘錄對(duì)象存儲(chǔ)其內(nèi)部狀態(tài)。
客戶端角色有負(fù)責(zé)保存?zhèn)渫泴?duì)象的責(zé)任。
源代碼
窄接口MementoIF,這是一個(gè)標(biāo)識(shí)接口,因此它沒(méi)有定義出任何的方法。
public interface MementoIF { }
發(fā)起人角色同時(shí)還兼任負(fù)責(zé)人角色,也就是說(shuō)它自己負(fù)責(zé)保持自己的備忘錄對(duì)象?!?nbsp;
public class Originator { public String state; /** * 改變狀態(tài) */ public void changeState(String state){ this.state = state; System.out.println("狀態(tài)改變?yōu)椋?quot; + state); } /** * 工廠方法,返還一個(gè)新的備忘錄對(duì)象 */ public Memento createMemento(){ return new Memento(this); } /** * 將發(fā)起人恢復(fù)到備忘錄對(duì)象所記錄的狀態(tài)上 */ public void restoreMemento(MementoIF memento){ Memento m = (Memento)memento; changeState(m.state); } private class Memento implements MementoIF{ private String state; /** * 構(gòu)造方法 */ private Memento(Originator o){ this.state = o.state; } private String getState() { return state; } } }
客戶端角色類
public class Client { public static void main(String[] args) { Originator o = new Originator(); //修改狀態(tài) o.changeState("state 0"); //創(chuàng)建備忘錄 MementoIF memento = o.createMemento(); //修改狀態(tài) o.changeState("state 1"); //按照備忘錄恢復(fù)對(duì)象的狀態(tài) o.restoreMemento(memento); } }
由于“自述歷史”作為一個(gè)備忘錄模式的特殊實(shí)現(xiàn)形式非常簡(jiǎn)單易懂,它可能是備忘錄模式最為流行的實(shí)現(xiàn)形式。