備忘錄設計模式知識概括
備忘錄設計模式知識概括
備忘錄設計模式簡介
遊戲角色狀態恢復問題:
- 遊戲角色有攻擊力和防禦力,在大戰Boss前儲存自身的狀態(攻擊力和防禦力), 當大戰Boss後攻擊力和防禦力下降,然後從備忘錄物件恢復到大戰前的狀態
傳統方案解決遊戲角色恢復:
- 類圖:
傳統的方式的問題分析:
- 一個物件,就對應一個儲存物件狀態的物件, 這樣當我們遊戲的物件很多時,不利於管理,開銷也很大
- 傳統的方式是簡單地做備份, new 出另外一個物件出來,再把需要備份的資料放到這個新物件,但這就暴露了物件內部的細節
- 解決方案: ==> 備忘錄模式
備忘錄模式基本介紹:
- 備忘錄模式(Memento Pattern)在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態
- 可以這裡理解備忘錄模式:現實生活中的備忘錄是用來記錄某些要去做的事情,或者是記錄已經達成的共同意見的事情,以防忘記了。
- 而在軟體層面,備忘錄模式有著相同的含義,備忘錄物件主要用來記錄一個物件的某種狀態,或者某些資料,當要做回退時,可以從備忘錄物件裡獲取原來的資料進行恢復操作
- 備忘錄模式屬於行為型模式
備忘錄模式原理類圖:
- Originator :物件(需要儲存狀態的物件)
- Memento :備忘錄物件,負責儲存好記錄, 即 Originator 內部狀態
- Caretaker:守護者物件,負責儲存多個備忘錄物件, 使用集合管理, 提高效率
- 說明:如果希望儲存多個 Originator 物件的不同時間的狀態,只需要使用 HashMap <String, Collection> 儲存即可,String 為 Originator 物件的唯一標識(key),Collection 為 Originator 物件不同時間的備忘錄集合
程式碼實現:
Originator:實體類,該類的例項為需要儲存狀態的物件,saveStateMemento() 方法用於返回一個備忘錄物件,getStateFromMemento() 方法用於從備忘錄
public class Originator {
private String state;// 狀態資訊
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
// 編寫一個方法,可以儲存一個狀態物件 Memento
// 因此編寫一個方法,返回 Memento
public Memento saveStateMemento() {
return new Memento(state);
}
// 通過備忘錄物件,恢復狀態
public void getStateFromMemento(Memento memento) {
state = memento.getState();
}
}
Memento:備忘錄物件,負責儲存物件的狀態
public class Memento {
private String state;
// 構造器
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
Caretker:聚合了備忘錄的集合,即 List
public class Caretaker {
// 在List 集合中會有很多的備忘錄物件
private List<Memento> mementoList = new ArrayList<Memento>();
public void add(Memento memento) {
mementoList.add(memento);
}
// 獲取到第index個Originator 的 備忘錄物件(即儲存狀態)
public Memento get(int index) {
return mementoList.get(index);
}
}
Client:測試程式碼
public class Client {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
originator.setState(" 狀態#1 攻擊力 100 "); // 設定攻擊速度
caretaker.add(originator.saveStateMemento()); // 儲存了當前的狀態
originator.setState(" 狀態#2 攻擊力 80 "); // 設定攻擊速度
caretaker.add(originator.saveStateMemento()); // 儲存了當前的狀態
originator.setState(" 狀態#3 攻擊力 50 "); // 設定攻擊速度
caretaker.add(originator.saveStateMemento()); // 儲存了當前的狀態
System.out.println("當前的狀態是 =" + originator.getState());
// 希望得到狀態 1, 將 originator 恢復到狀態1
originator.getStateFromMemento(caretaker.get(0)); // 恢復物件屬性
System.out.println("恢復到狀態1 , 當前的狀態是");
System.out.println("當前的狀態是 =" + originator.getState());
}
}
備忘錄模式解決遊戲角色恢復
簡述:
- 應用例項:遊戲角色有攻擊力和防禦力,在大戰Boss前儲存自身的狀態(攻擊力和防禦力), 當大戰Boss後攻擊力和防禦力下降, 然後從備忘錄物件恢復到大戰前的狀態
- 類圖:
- 程式碼實現:
GameRole:遊戲角色對應的實體類,createMemento() 方法用於建立備忘錄物件,recoverGameRoleFromMemento() 用於從備忘錄物件中恢復角色的狀態
public class GameRole {
private int vit;
private int def;
// 建立Memento ,即根據當前的狀態得到Memento
public Memento createMemento() {
return new Memento(vit, def);
}
// 從備忘錄物件,恢復GameRole的狀態
public void recoverGameRoleFromMemento(Memento memento) {
this.vit = memento.getVit();
this.def = memento.getDef();
}
// 顯示當前遊戲角色的狀態
public void display() {
System.out.println("遊戲角色當前的攻擊力:" + this.vit + " 防禦力: " + this.def);
}
public int getVit() {
return vit;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
}
Memento:備忘錄物件
public class Memento {
// 攻擊力
private int vit;
// 防禦力
private int def;
public Memento(int vit, int def) {
this.vit = vit;
this.def = def;
}
public int getVit() {
return vit;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
}
Caretaker:守護者物件,用於管理備忘錄物件
//守護者物件, 儲存遊戲角色的狀態
public class Caretaker {
// 如果只儲存一次狀態
private Memento memento;
// 對GameRole 儲存多次狀態
// private ArrayList<Memento> mementos;
// 對多個遊戲角色儲存多個狀態
// private HashMap<String, ArrayList<Memento>> rolesMementos;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
Client:測試程式碼
public class Client {
public static void main(String[] args) {
// 建立遊戲角色
GameRole gameRole = new GameRole();
gameRole.setVit(100);
gameRole.setDef(100);
System.out.println("和boss大戰前的狀態");
gameRole.display();
// 把當前狀態儲存caretaker
Caretaker caretaker = new Caretaker();
caretaker.setMemento(gameRole.createMemento());
System.out.println("和boss大戰~~~");
gameRole.setDef(30);
gameRole.setVit(30);
gameRole.display();
System.out.println("大戰後,使用備忘錄物件恢復元氣");
gameRole.recoverGameRoleFromMemento(caretaker.getMemento());
System.out.println("恢復後的狀態");
gameRole.display();
}
}
備忘錄模式的注意事項和細節
- 給使用者提供了一種可以恢復狀態的機制,可以使使用者能夠比較方便地回到某個歷史的狀態
- 實現了資訊的封裝,使得使用者不需要關心狀態的儲存細節
- 如果類的成員變數過多,勢必會佔用比較大的資源,而且每一次儲存都會消耗一定的記憶體,這個需要注意
- 為了節約記憶體,備忘錄模式可以和原型模式配合使用
相關文章
- 迭代器設計模式知識概括設計模式
- 設計模式----備忘錄模式設計模式
- 觀察者設計模式知識概括設計模式
- 直譯器設計模式知識概括設計模式
- 設計模式之備忘錄模式設計模式
- 設計模式 - 備忘錄模式 ( Memento )設計模式
- GoLang設計模式11 - 備忘錄模式Golang設計模式
- 極簡設計模式-備忘錄模式設計模式
- 簡說設計模式——備忘錄模式設計模式
- 設計模式漫談之備忘錄模式設計模式
- 19.java設計模式之備忘錄模式Java設計模式
- 設計模式 | 備忘錄模式及典型應用設計模式
- 折騰Java設計模式之備忘錄模式Java設計模式
- 抽絲剝繭——備忘錄設計模式設計模式
- Rust語言之GoF設計模式:備忘錄Memento模式RustGo設計模式
- 行為型設計模式 - 備忘錄模式詳解設計模式
- 《設計模式七》備忘錄、模板方法、狀態模式及設計模式設計總結設計模式
- 無廢話設計模式(16)行為型模式--備忘錄模式設計模式
- 設計模式(Swift) - 2.單例模式、備忘錄模式和策略模式設計模式Swift單例
- 軟體設計模式學習(二十二)備忘錄模式設計模式
- 備忘錄模式(Memento)模式
- Swift 中的設計模式 #2 觀察者模式與備忘錄模式Swift設計模式
- 設計模式學習筆記(十八)備忘錄模式及其實現設計模式筆記
- Java進階篇設計模式之十二 ---- 備忘錄模式和狀態模式Java設計模式
- 19_備忘錄模式模式
- 行為型模式:備忘錄模式模式
- 如何給備忘錄設計密碼?Mac上備忘錄設定密碼教程密碼Mac
- 設計模式 第十章 備忘錄模式、直譯器模式、狀態模式設計模式
- 基本的設計模式概括設計模式
- Python知識概括Python
- HTML知識概括HTML
- 設計模式(二十)——備忘錄模式(遊戲角色狀態恢復問題)設計模式遊戲
- 實驗 20:備忘錄模式模式
- 第 22 章 備忘錄模式模式
- Android備忘錄《單例模式》Android單例模式
- 設計模式必備知識點---六大設計原則設計模式
- 我用備忘錄模式設計了簡易的版本控制系統模式
- 11.21實驗 20:備忘錄模式模式