源碼地址 | https://github.com/DingMouRen/DesignPattern |
---|
備忘錄模式.png
- Originator 原發器,負責創建一個備忘錄,可以記錄、恢復自身的內部狀態,同時還可以根據需要決定Memento存儲自身的哪些狀態。
- Memento 備忘錄角色,用于存儲Originator的內部狀態,并且可以防止Originator以外的對象訪問Memento.
- Caretaker 管理者,負責存儲備忘錄,不能對備忘錄的內容進行操作和訪問,只能將備忘錄傳遞給其他對象。
定義
備忘錄模式在不破壞封閉的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態,這樣就可以將該對象恢復到原來保存的狀態。
使用場景
- 需要保存一個對象在某一個時刻的狀態或部分狀態
- 如果用一個接口來讓其他對象得到這些狀態,將會暴露對象的實現細節并破壞對象的封裝性。一個對象不希望外界直接訪問其內部狀態,通過中間對象可以間接訪問其內部狀態。
舉個例子
我們玩游戲的時候都有游戲存檔的事情,基本流程:游戲開始--獲取存檔信息--開始游戲--退出游戲時進行存檔,循環往復。
//備忘錄類
public class Memoto {
private int checkPoint;//關數
private int lifeValue;//血量
private String weapon;//武器
public int getCheckPoint() {
return checkPoint;
}
public void setCheckPoint(int checkPoint) {
this.checkPoint = checkPoint;
}
public int getLifeValue() {
return lifeValue;
}
public void setLifeValue(int lifeValue) {
this.lifeValue = lifeValue;
}
public String getWeapon() {
return weapon;
}
public void setWeapon(String weapon) {
this.weapon = weapon;
}
@Override
public String toString() {
return "備忘錄中存儲的游戲關數:"+checkPoint+" 血量:"+lifeValue+" 武器:"+weapon;
}
}
//相當于Originator,
public class Game {
private int checkPoint = 1;//游戲第一關
private int lifeValue = 100;//剛開始血量滿滿
private String weapon = "匕首";//武器
//開始游戲
public void play(){
System.out.println("開始游戲:"+String.format("第%d關",checkPoint)+" fighting!! ︻$▅▆▇◤");
lifeValue -= 10;
System.out.println("闖關成功");
checkPoint++;
System.out.println("到達"+String.format("第%d關",checkPoint));
}
//退出游戲
public void quit(){
System.out.println(". . . . . .");
System.out.println(this.toString()+"\n退出游戲");
}
//創建備忘錄
public Memoto createMemoto(){
Memoto memoto = new Memoto();
memoto.setCheckPoint(this.checkPoint);
memoto.setLifeValue(lifeValue);
memoto.setWeapon(weapon);
return memoto;
}
//恢復游戲
public void restore(Memoto memoto){
this.checkPoint = memoto.getCheckPoint();
this.lifeValue = memoto.getLifeValue();
this.weapon = memoto.getWeapon();
System.out.println("恢復后的游戲狀態:"+this.toString());
}
@Override
public String toString() {
return "當前游戲關數:"+checkPoint+" 血量:"+lifeValue+" 武器:"+weapon;
}
}
//管理者 管理備忘錄
public class Caretaker {
private Memoto memoto;//備忘錄
//存檔
public void saveMemoto(Memoto memoto){
this.memoto = memoto;
}
//獲取存檔
public Memoto getMemoto() {
return memoto;
}
}
使用
public static void main(String[] args) {
//構建游戲對象
Game game = new Game();
//構建管理者
Caretaker caretaker = new Caretaker();
//開始游戲
game.play();
//游戲存檔
caretaker.saveMemoto(game.createMemoto());
//退出游戲
game.quit();
//進入游戲時,恢復上一次游戲的狀態
Game newGame = new Game();
System.out.println("登錄游戲");
newGame.restore(caretaker.getMemoto());
}
總結
備忘錄模式是在不破壞封裝的條件下,通過備忘錄對象Memoto存儲另外一個對象內部狀態的快照,在將來合適的時候把這個對象還原到存儲的狀態。
備忘錄模式優點自然是為用戶提供了一個可以恢復狀態的機制,可以讓用戶方便的回到某個歷史的狀態,缺點就是在類成員變量變多的情況下,勢必消耗資源,每一次保存都會消耗一定的內存。