1.備忘錄模式簡(jiǎn)介
備忘錄模式(Memento Pattern)模式是是行為型(Behavioral)設(shè)計(jì)模式,在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài),這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)。備忘錄模式是撤銷功能的實(shí)現(xiàn)。
備忘錄模式一共有三種角色:
(1) Originator(發(fā)起人):記錄當(dāng)前時(shí)刻的內(nèi)部狀態(tài),負(fù)責(zé)定義哪些屬于備份范圍的狀態(tài),負(fù)責(zé)創(chuàng)建和恢復(fù)備忘錄數(shù)據(jù)。
(2) Memento(備忘錄):負(fù)責(zé)存儲(chǔ)發(fā)起人對(duì)象的內(nèi)部狀態(tài),在需要的時(shí)候提供發(fā)起人需要的內(nèi)部狀態(tài)。
(3) Caretaker(管理人):負(fù)責(zé)保存?zhèn)渫洠吞峁﹤渫?,不知道備忘錄中的?xì)節(jié)。
2. 備忘錄模式舉例
下面做一個(gè)備份文本,修改文本,再把文本恢復(fù)到初始狀態(tài)的例子。
| 序號(hào) | 類名 | 角色 | 說(shuō)明 |
|---|---|---|---|
| 1 | Originator | Originator | 發(fā)起人,對(duì)文本做操作 |
| 2 | Memento | Memento | 備忘錄,備份文本 |
| 3 | Caretaker | Caretaker | 管理人,存儲(chǔ)備忘錄 |
| 4 | MementoMain | 客戶端 | 演示調(diào)用 |

1. Memento 備忘錄
/**
* Memento(備忘錄):負(fù)責(zé)備份Originator的文本內(nèi)容,并在恢復(fù)的時(shí)候,提供文本內(nèi)容
*/
public class Memento {
// 備份的屬性
private String text;
public Memento(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
**2. Originator 發(fā)起人 **
/**
* Originator(發(fā)起人):對(duì)文本做操作,并定義備份范圍
*/
public class Originator {
// 文本
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
// 創(chuàng)建備份(備忘錄)
public Memento createMemento(){
return new Memento(text);
}
// 從備份中恢復(fù)。
public void restoreMemento(Memento memento){
setText(memento.getText());
}
}
3. Caretaker,管理人
/**
* Caretaker(管理人):負(fù)責(zé)保存?zhèn)渫?,和提供備忘錄,不知道備忘錄中的?xì)節(jié)。
*/
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
4. MementoMain 演示類
public class MementoMain {
public static void main(String[] args) {
// 初始操作
Originator originator = new Originator();
originator.setText("我愛(ài)Java");
System.out.println("初始內(nèi)容:" + originator.getText());
// 備份操作
Caretaker caretaker = new Caretaker();
caretaker.setMemento(originator.createMemento());
// 修改操作
originator.setText("我愛(ài)Python");
System.out.println("修改后的內(nèi)容:" + originator.getText());
// 恢復(fù)操作
originator.restoreMemento(caretaker.getMemento());
System.out.println("恢復(fù)后的內(nèi)容:" + originator.getText());
}
}
結(jié)果輸出
初始內(nèi)容:我愛(ài)Java
修改后的內(nèi)容:我愛(ài)Python
恢復(fù)后的內(nèi)容:我愛(ài)Java
本例只是單狀態(tài)的備份和恢復(fù),通常情況下,都是多狀態(tài)的備份和恢復(fù),例如棋類軟件中的悔棋,文本編輯器中的undo,我們可以在備忘錄中,使用Map來(lái)存儲(chǔ)所有的狀態(tài)。
3. 總結(jié)
備忘錄模式的好處在于,當(dāng)發(fā)起人的狀態(tài)改變時(shí),如果出現(xiàn)錯(cuò)誤,就可以使用備忘錄回退;備份的狀態(tài)是保存在備忘錄中,是在發(fā)起人角色之外的。壞處在于,備份越多,消耗的資源就越多。
(完)