PHP設(shè)計模式——備忘錄模式

備忘錄模式又叫做快照模式或Token模式,在不破壞封閉的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。這樣以后就可將該對象恢復(fù)到原先保存的狀態(tài)。
UML類圖:


圖片.png

角色:

1.發(fā)起人(GameRole):負(fù)責(zé)創(chuàng)建一個備忘錄,用以記錄當(dāng)前時刻自身的內(nèi)部狀態(tài),并可使用備忘錄恢復(fù)內(nèi)部狀態(tài)。發(fā)起人可以根據(jù)需要決定備忘錄存儲自己的哪些內(nèi)部狀態(tài)。

2.備忘錄(RoleStateSaveBox):負(fù)責(zé)存儲發(fā)起人對象的內(nèi)部狀態(tài),并可以防止發(fā)起人以外的其他對象訪問備忘錄。備忘錄有兩個接口:管理者只能看到備忘錄的窄接口,他只能將備忘錄傳遞給其他對象。發(fā)起人卻可看到備忘錄的寬接口,允許它訪問返回到先前狀態(tài)所需要的所有數(shù)據(jù)。

3.管理者(GameRoleStateManager):負(fù)責(zé)存取備忘錄,不能對的內(nèi)容進(jìn)行訪問或者操作。

核心代碼:

<?php
/**
 * Created by PhpStorm.
 * User: Jang
 * Date: 2015/6/10
 * Time: 9:49
 */
 
//游戲角色
class GameRole
{
    #region 游戲角色狀態(tài)屬性(生命力、攻擊力、防御力)
    public $liveLevel;
 
    public $attackLevel;
 
    public $defenseLevel;
    #endregion
 
    //保存狀態(tài)
    public function SaveState()
    {
        return (new RoleStateMemento($this->liveLevel,$this->attackLevel,$this->defenseLevel));
    }
 
    //恢復(fù)狀態(tài)
    public function RecoveryState(RoleStateMemento $_memento)
    {
        $this->liveLevel = $_memento->liveLevel;
        $this->attackLevel = $_memento->attackLevel;
        $this->defenseLevel = $_memento->defenseLevel;
    }
 
    //------------其他屬性及操作--------------
    //獲得初始狀態(tài)
    public function GetInitState()
    {
        $this->defenseLevel = 100;
        $this->attackLevel = 100;
        $this->liveLevel = 100;
    }
 
    //狀態(tài)顯示
    public function StateDisplay()
    {
        echo "角色狀態(tài):<br/>";
        echo "生命力:{$this->liveLevel}<br/>";
        echo "攻擊力:{$this->attackLevel}<br/>";
        echo "防御力:{$this->defenseLevel}<br/>";
    }
 
    //被攻擊
    public function BeenAttack()
    {
        $this->liveLevel -= 9.5;
        if($this->liveLevel<=0)
        {
            $this->liveLevel = 0;
            echo "呃,該角色陣亡了!<br/>";
            echo "Game Over!<br/>";
            return;
        }
 
        $this->attackLevel -= 1.1;
        if($this->attackLevel<=0)
        {
            $this->attackLevel = 0;
        }
 
        $this->defenseLevel -= 0.5;
        if($this->defenseLevel<=0)
        {
            $this->defenseLevel = 0;
        }
    }
    }
 
//角色狀態(tài)存儲箱類
class RoleStateMemento
{
    public $liveLevel;
    public $attackLevel;
    public $defenseLevel;
 
    public function RoleStateMemento($_ll,$_al,$_dl)
    {
        $this->liveLevel=$_ll;
        $this->attackLevel=$_al;
        $this->defenseLevel=$_dl;
    }
}
 
//游戲角色狀態(tài)管理者類
class RoleStateManager
{
    public $memento;
}

測試代碼:

<?php
/**
 * Created by PhpStorm.
 * User: Jang
 * Date: 2015/6/10
 * Time: 10:02
 */
 
header("Content-Type:text/html;charset=utf-8");
//-------------------------備忘錄模式------------------------
require_once "./Memento/Memento.php";
 
//開戰(zhàn)前
$ufo = new GameRole();
$ufo->GetInitState();
echo "<span style='color:#ff0000'>----------------開戰(zhàn)前-----------------</span><br/>";
$ufo->StateDisplay();
 
//保存進(jìn)度
$roleMan = new RoleStateManager();
$roleMan->memento = $ufo->SaveState();
 
echo "<span style='color:#ff0000'>----------------戰(zhàn)斗中-----------------</span><br/>";
$num=1;
//大戰(zhàn)Boss5個回合
for ($i = 0; $i <13;$i++ )
{
    echo "-------------第{$num}回合-------------<br/>";
    $ufo->BeenAttack();
    $ufo->StateDisplay();
    $num++;
    //角色陣亡
    if($ufo->liveLevel<=0)
    {
        break;
    }
}
 
echo "<span style='color:#ff0000'>----------------恢復(fù)狀態(tài)-----------------</span><br/>";
//恢復(fù)之前狀態(tài)
$ufo->RecoveryState($roleMan->memento);
$ufo->StateDisplay();

優(yōu)點:

1、有時一些發(fā)起人對象的內(nèi)部信息必須保存在發(fā)起人對象以外的地方,但是必須要由發(fā)起人對象自己讀取,這時,使用備忘錄模式可以把復(fù)雜的發(fā)起人內(nèi)部信息對其他的對象屏蔽起來,從而可以恰當(dāng)?shù)乇3址庋b的邊界。

2、本模式簡化了發(fā)起人類。發(fā)起人不再需要管理和保存其內(nèi)部狀態(tài)的一個個版本,客戶端可以自行管理他們所需要的這些狀態(tài)的版本。

缺點:

1、如果發(fā)起人角色的狀態(tài)需要完整地存儲到備忘錄對象中,那么在資源消耗上面?zhèn)渫泴ο髸馨嘿F。

2、當(dāng)負(fù)責(zé)人角色將一個備忘錄存儲起來的時候,負(fù)責(zé)人可能并不知道這個狀態(tài)會占用多大的存儲空間,從而無法提醒用戶一個操作是否很昂貴。

參考:《大話設(shè)計模式》,作者程杰
https://blog.csdn.net/jhq0113/article/details/46438735

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容