備忘錄模式又叫做快照模式或Token模式,在不破壞封閉的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以後就可將該對象恢復到原先保存的狀態。
UML類圖:
角色:
1.發起人(GameRole):負責創建一個備忘錄,用以記錄當前時刻自身的內部狀態,並可使用備忘錄恢復內部狀態。發起人可以根據需要決定備忘錄存儲自己的哪些內部狀態。
2.備忘錄(RoleStateSaveBox):負責存儲發起人對象的內部狀態,並可以防止發起人以外的其他對象訪問備忘錄。備忘錄有兩個接口:管理者只能看到備忘錄的窄接口,他只能將備忘錄傳遞給其他對象。發起人卻可看到備忘錄的寬接口,允許它訪問返回到先前狀態所需要的所有數據。
3.管理者(GameRoleStateManager):負責存取備忘錄,不能對的內容進行訪問或者操作。
核心代碼:
liveLevel,$this->attackLevel,$this->defenseLevel)); } //恢復狀態 public function RecoveryState(RoleStateMemento $_memento) { $this->liveLevel = $_memento->liveLevel; $this->attackLevel = $_memento->attackLevel; $this->defenseLevel = $_memento->defenseLevel; } //------------其他屬性及操作-------------- //獲得初始狀態 public function GetInitState() { $this->defenseLevel = 100; $this->attackLevel = 100; $this->liveLevel = 100; } //狀態顯示 public function StateDisplay() { echo 角色狀態: ; echo 生命力:{$this->liveLevel} ; echo 攻擊力:{$this->attackLevel} ; echo 防御力:{$this->defenseLevel} ; } //被攻擊 public function BeenAttack() { $this->liveLevel -= 9.5; if($this->liveLevel<=0) { $this->liveLevel = 0; echo 呃,該角色陣亡了! ; echo Game Over! ; return; } $this->attackLevel -= 1.1; if($this->attackLevel<=0) { $this->attackLevel = 0; } $this->defenseLevel -= 0.5; if($this->defenseLevel<=0) { $this->defenseLevel = 0; } } } //角色狀態存儲箱類 class RoleStateMemento { public $liveLevel; public $attackLevel; public $defenseLevel; public function RoleStateMemento($_ll,$_al,$_dl) { $this->liveLevel=$_ll; $this->attackLevel=$_al; $this->defenseLevel=$_dl; } } //游戲角色狀態管理者類 class RoleStateManager { public $memento; }
GetInitState(); echo ----------------開戰前----------------- ; $ufo->StateDisplay(); //保存進度 $roleMan = new RoleStateManager(); $roleMan->memento = $ufo->SaveState(); echo ----------------戰斗中----------------- ; $num=1; //大戰Boss5個回合 for ($i = 0; $i <13;$i++ ) { echo -------------第{$num}回合------------- ; $ufo->BeenAttack(); $ufo->StateDisplay(); $num++; //角色陣亡 if($ufo->liveLevel<=0) { break; } } echo ----------------恢復狀態----------------- ; //恢復之前狀態 $ufo->RecoveryState($roleMan->memento); $ufo->StateDisplay();
優點:
1、有時一些發起人對象的內部信息必須保存在發起人對象以外的地方,但是必須要由發起人對象自己讀取,這時,使用備忘錄模式可以把復雜的發起人內部信息對其他的對象屏蔽起來,從而可以恰當地保持封裝的邊界。
2、本模式簡化了發起人類。發起人不再需要管理和保存其內部狀態的一個個版本,客戶端可以自行管理他們所需要的這些狀態的版本。
缺點:
1、如果發起人角色的狀態需要完整地存儲到備忘錄對象中,那麼在資源消耗上面備忘錄對象會很昂貴。
2、當負責人角色將一個備忘錄存儲起來的時候,負責人可能並不知道這個狀態會占用多大的存儲空間,從而無法提醒用戶一個操作是否很昂貴。
歡迎關注我的視頻課程,地址如下,謝謝。
PHP面向對象設計模式