概念
在不破壞封閉的前提下施籍,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài)瓤摧,并在該對(duì)象之外保存這個(gè)狀態(tài)腻异。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)给赞。
角色
Originator(發(fā)起人):負(fù)責(zé)創(chuàng)建一個(gè)備忘錄Memento,用以記錄當(dāng)前時(shí)刻自身的內(nèi)部狀態(tài),并可使用備忘錄恢復(fù)內(nèi)部狀態(tài)空免。Originator可以根據(jù)需要決定Memento存儲(chǔ)自己的哪些內(nèi)部狀態(tài)征字。
Memento(備忘錄):負(fù)責(zé)存儲(chǔ)Originator對(duì)象的內(nèi)部狀態(tài),并可以防止Originator以外的其他對(duì)象訪問備忘錄浦楣。備忘錄有兩個(gè)接口:Caretaker只能看到備忘錄的窄接口油狂,他只能將備忘錄傳遞給其他對(duì)象弱贼。Originator卻可看到備忘錄的寬接口,允許它訪問返回到先前狀態(tài)所需要的所有數(shù)據(jù)。
Caretaker(管理者):負(fù)責(zé)備忘錄Memento匪凉,不能對(duì)Memento的內(nèi)容進(jìn)行訪問或者操作聂受。
源代碼
/**
* 備忘錄類
*/
public class Memento {
/**
* 需要備份的相關(guān)數(shù)據(jù)
*/
private String state1;
private String state2;
/**
* 創(chuàng)建備忘錄時(shí)將相關(guān)數(shù)據(jù)導(dǎo)入
* @param state1
* @param state2
*/
public Memento(String state1, String state2) {
this.state1 = state1;
this.state2 = state2;
}
//取出備份的數(shù)據(jù)
public String getState1() {
return state1;
}
public String getState2() {
return state2;
}
}
/**
* 發(fā)起人類
*/
public class Originator {
//需要保存的屬性
private String state1;
private String state2;
/**
* 創(chuàng)建備忘錄镜悉,將當(dāng)前需要保存的數(shù)據(jù)導(dǎo)入并創(chuàng)建一個(gè)備忘錄對(duì)象
* @return
*/
public Memento createMemento(){
return new Memento(state1, state2);
}
/**
* 恢復(fù)數(shù)據(jù),將備忘錄導(dǎo)入并回復(fù)數(shù)據(jù)
* @param memento
*/
public void resetMemento(Memento memento){
this.state1 = memento.getState1();
this.state2 = memento.getState2();
}
public void show(){
System.out.println("state1:" + state1);
System.out.println("state2:" + state2);
}
public String getState1() {
return state1;
}
public void setState1(String state1) {
this.state1 = state1;
}
public String getState2() {
return state2;
}
public void setState2(String state2) {
this.state2 = state2;
}
}
/**
* 管理者怖竭,管理備忘錄
*/
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
/**
* 客戶端
*/
public class Client {
public static void main(String[] args) {
//創(chuàng)建一個(gè)發(fā)起人
Originator originator = new Originator();
originator.setState1("mjp");
originator.setState2("rtt");
originator.show();
//創(chuàng)建一個(gè)管理者
Caretaker caretaker = new Caretaker();
caretaker.setMemento(originator.createMemento());
//狀態(tài)改變
System.out.println("---狀態(tài)改變---");
originator.setState1("馬俊鵬");
originator.setState2("任婷婷");
originator.show();
//狀態(tài)恢復(fù)
System.out.println("---狀態(tài)恢復(fù)---");
originator.resetMemento(caretaker.getMemento());
originator.show();
}
}
總結(jié)
Memento模式適用于功能比較復(fù)雜绽左,但需要維護(hù)或記錄屬性歷史的類拼窥,或者需要保存的屬性只是眾多屬性中的一部分時(shí)情龄,Originator可以根據(jù)保存的Memento信息還原特定的屬性到前一狀態(tài)专酗。
如果在某個(gè)系統(tǒng)中使用命令模式時(shí)佑笋,需要實(shí)現(xiàn)撤銷命令的功能颠锉,那么命令模式可以使用備忘錄模式來存儲(chǔ)可撤銷操作的狀態(tài)瓷蛙。
使用備忘錄模式可以把復(fù)雜的對(duì)象內(nèi)部信息對(duì)其他的對(duì)象屏蔽起來冠桃,從而可以恰當(dāng)?shù)谋3址庋b的邊界葬项。