備用錄模式是一種行為型設計模式,用于保存對象當前的狀態,以便之后可以再次恢復到此狀態。
備忘錄模式要保證保存的對象狀態不能被對象從外部訪問,保護好被保存的這些對象狀態的完整性以及內部實現不向外部暴露。
定義
在不破壞封裝性的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態,這樣以后就可將該對象恢復到原先保存的狀態。
使用場景
- 需要保存一個對象在某個適合的全部或部分狀態時。
- 一個對象不希望外部直接訪問其內部狀態時。
UML
- Originator:負責創建一個備忘錄,可以記錄,恢復自身內部的狀態。同時可以決定哪些狀態需要備忘。
- Memoto:備忘錄角色,用于存儲Originator的內部狀態,并且可以防止Originator之外的對象訪問Memoto。
- Caretaker:負責存儲備忘錄,不能對備忘錄的內容進行操作和訪問,只能講備忘錄傳遞給其他對象。
看這個解釋可能有點暈,直接看一下實例就很清晰了。
簡單實現
最容易理解的就是子啊游戲中的存檔了。一般在打boss之前,都會存個檔,以便于之后直接開始打boss。這個存檔就包含了我們當前的狀態,被boss打死后,下次讀取存檔就會回到這個狀態,方便挑戰boss。
首先是一個玩家類,包含各種玩法以及玩家自身狀態。然后提供了保存生成當前狀態的封裝類和從保存的裝套中恢復的方法。
public class Player {
private int lv = 1;
private int hp = 100;
private int mp = 50;
public void play(){
lv++;
hp+=100;
mp+=50;
System.out.println("升級了,當前級別"+lv+" hp:"+hp+" mp:"+mp);
}
public void attackBoss(){
hp-=80;
mp-=40;
System.out.println("打boss之后,當前級別"+lv+" hp:"+hp+" mp:"+mp);
}
public Memoto createMemoto(){
Memoto memoto = new Memoto();
memoto.lv = lv;
memoto.hp = hp;
memoto.mp = mp;
return memoto;
}
public void restore(Memoto memoto){
lv = memoto.lv;
hp = memoto.hp;
mp = memoto.mp;
System.out.println("回檔了,當前級別"+lv+" hp:"+hp+" mp:"+mp);
}
@Override
public String toString() {
return "當前狀態:級別"+lv+" hp:"+hp+" mp:"+mp;
}
}
然后是備忘錄對象,存儲玩家狀態
public class Memoto {
public int lv;
public int hp;
public int mp;
}
最后是備忘錄操作者者,用來存儲和返回備忘錄對象
public class Caretaker {
private Memoto memoto;
public void save(Memoto memoto){
this.memoto=memoto;
}
public Memoto load(){
return memoto;
}
}
客戶端調用:
public class Client {
public static void main(String[] args) {
Player player = new Player();
player.toString();
player.play();
player.toString();
System.out.println("存檔");
Caretaker caretaker = new Caretaker();
caretaker.save(player.createMemoto());
player.attackBoss();
player.toString();
player.restore(caretaker.load());
player.toString();
}
}
輸出:
打完boss后,紅和藍都不滿了,想重新回到打boss之前的狀態就直接恢復之前備份的狀態就行了。
當然,真實的游戲中你的游戲進度也會保存在存檔中,恢復了狀態肯定也要重新打boss了。
Android中的備忘錄模式
在Activity中有這兩個方法:
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
我們在用他們的時候目的就是為了保存Activity當前的狀態,所以這個就是個備忘錄模式。當然,操作者,備份和恢復過程等,已經被系統幫忙做了一部分。
總結
優點
- 提供了一種備份恢復機制,使用戶能方便的回到某個時刻的狀態。
- 保存的狀態是保存在發起人之外的類的,實現了對保存的狀態的封裝。發起人就不需要對備份進行管理了。
缺點
- 每一次保存都會消耗一定的內存。當保存的狀態非常多的時候,會非常消耗資源。