設計模式之備忘錄模式
備忘錄(Memento)模式又稱標記(Token)模式。GOF給備忘錄模式的定義為:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態。這樣以后就可將該對象恢復到原先保存的狀態。
其實單就實現保存一個對象在某一時刻的狀態的功能,還是很簡單的——將對象中要保存的屬性放到一個專門管理備份的對象中,需要的時候則調用約定好的方法將備份的屬性放回到原來的對象中去。
備忘錄模式的組成部分:
1) 備忘錄(Memento)角色:備忘錄角色存儲“備忘發起角色”的內部狀態。“備忘發起角色”根據需要決定備忘錄角色存儲“備忘發起角色”的哪些內部狀 態。為了防止“備忘發起角色”以外的其他對象訪問備忘錄。備忘錄實際上有兩個接口,“備忘錄管理者角色”只能看到備忘錄提供的窄接口——對于備忘錄角色中 存放的屬性是不可見的。“備忘發起角色”則能夠看到一個寬接口——能夠得到自己放入備忘錄角色中屬性。
2) 備忘發起(Originator)角色:“備忘發起角色”創建一個備忘錄,用以記錄當前時刻它的內部狀態。在需要時使用備忘錄恢復內部狀態。
3) 備忘錄管理者(Caretaker)角色:負責保存好備忘錄。不能對備忘錄的內容進行操作或檢查。
1) 備忘錄(Memento)角色:備忘錄角色存儲“備忘發起角色”的內部狀態。“備忘發起角色”根據需要決定備忘錄角色存儲“備忘發起角色”的哪些內部狀 態。為了防止“備忘發起角色”以外的其他對象訪問備忘錄。備忘錄實際上有兩個接口,“備忘錄管理者角色”只能看到備忘錄提供的窄接口——對于備忘錄角色中 存放的屬性是不可見的。“備忘發起角色”則能夠看到一個寬接口——能夠得到自己放入備忘錄角色中屬性。
2) 備忘發起(Originator)角色:“備忘發起角色”創建一個備忘錄,用以記錄當前時刻它的內部狀態。在需要時使用備忘錄恢復內部狀態。
3) 備忘錄管理者(Caretaker)角色:負責保存好備忘錄。不能對備忘錄的內容進行操作或檢查。
使用備忘錄模式的前提:
1) 必須保存一個對象在某一個時刻的(部分)狀態, 這樣以后需要時它才能恢復到先前的狀態。
2) 如果一個用接口來讓其它對象直接得到這些狀態,將會暴露對象的實現細節并破壞對象的封裝性。
例子如下:1) 必須保存一個對象在某一個時刻的(部分)狀態, 這樣以后需要時它才能恢復到先前的狀態。
2) 如果一個用接口來讓其它對象直接得到這些狀態,將會暴露對象的實現細節并破壞對象的封裝性。
//存儲信息類
public class Caretaker {
private Memento memento;
public Memento getMemento(){
return this.memento;
}
public void setMemento(Memento memento){
this.memento = memento;
}
}
public class Caretaker {
private Memento memento;
public Memento getMemento(){
return this.memento;
}
public void setMemento(Memento memento){
this.memento = memento;
}
}
//備忘錄模式
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
public class Originator {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento createMemento() {
return new Memento(state);
}
public void setMemento(Memento memento) {
state = memento.getState();
}
public void showState(){
System.out.println(state);
}
}
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento createMemento() {
return new Memento(state);
}
public void setMemento(Memento memento) {
state = memento.getState();
}
public void showState(){
System.out.println(state);
}
}
測試類:
public class Test {
public static void main(String[] args) {
Originator org = new Originator();
org.setState("開會中");
org.showState();//顯示
System.out.println("---------------");
Caretaker ctk = new Caretaker();
ctk.setMemento(org.createMemento());//將數據封裝在Caretaker
System.out.println("---------------");
org.setState("睡覺中");
org.showState();//顯示
System.out.println("---------------");
org.setMemento(ctk.getMemento());//將Caretaker中的數據重新導入
org.showState();
System.out.println("---------------");
}
}
public static void main(String[] args) {
Originator org = new Originator();
org.setState("開會中");
org.showState();//顯示
System.out.println("---------------");
Caretaker ctk = new Caretaker();
ctk.setMemento(org.createMemento());//將數據封裝在Caretaker
System.out.println("---------------");
org.setState("睡覺中");
org.showState();//顯示
System.out.println("---------------");
org.setMemento(ctk.getMemento());//將Caretaker中的數據重新導入
org.showState();
System.out.println("---------------");
}
}