PHP设计模式--备忘录模式

 备忘录模式(Memento) 是行为模式之一。
 概念:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

 从命名基本上可以了解到这个模式的作用,我们都知道无论是以前的手机还是现在的手机,都会有备忘录这个功能,备忘录的作用是什么呢?
 防止人脑记不住的时候,记录到备忘录里面,可以随时拿出来提醒自己,就像是日志文件一样。

 例如:作为开发人员,一定会用到的一个组合键Ctrl + Z就是这个原理。

 如下代码模拟水桶抽水多次回退效果。

<?php  
  
header("Content-Type:text/html;charset=utf-8");    
//-------------------------备忘录模式------------------------    
require_once "Memento.php";    
echo "<pre>";  
  
$water = new Bucket();    // 实例化水桶类  
$water->Initialize();     // 初始化赋值  
$water->ShowWaterLevel(); // 显示水位  
$SL = new SaveWater();    // 实例储水类  
  
echo "----------------------第一次抽水----------------------<br/>";  
$water->DrawOff();                      // 抽水  
$waterlevel = $water->SaveWaterLevel(); // 保存水位返回水位值  
$SL->SaveArrayWater($waterlevel);       // 存到备忘录  
$water->ShowWaterLevel();               // 展示水位  
  
echo "-----------------------回退一次----------------------<br/>";  
$water->RecoveryWaterLevel($SL->memento);// 回退水位  
$water->ShowWaterLevel();                // 展示水位  
  
echo "----------------------第二次抽水----------------------<br/>";  
$water->DrawOff();                      // 抽水  
$waterlevel = $water->SaveWaterLevel(); // 保存水位返回水位值  
$SL->SaveArrayWater($waterlevel);       // 存到备忘录  
$water->ShowWaterLevel();               // 展示水位  
  
echo "----------------------第三次抽水----------------------<br/>";  
$water->DrawOff();                      // 抽水  
$waterlevel = $water->SaveWaterLevel(); // 保存水位返回水位值  
$SL->SaveArrayWater($waterlevel);       // 存到备忘录  
$water->ShowWaterLevel();               // 展示水位  
  
  
echo "-----------------------回退一次----------------------<br/>";  
$water->RecoveryWaterLevel($SL->memento);// 回退水位  
$water->ShowWaterLevel();                // 展示水位  
  
  
echo "----------------------第四次抽水----------------------<br/>";  
$water->DrawOff();                      // 抽水  
$waterlevel = $water->SaveWaterLevel(); // 保存水位返回水位值  
$SL->SaveArrayWater($waterlevel);       // 存到备忘录  
$water->ShowWaterLevel();               // 展示水位  
  
echo "----------------------第五次抽水----------------------<br/>";  
$water->DrawOff();                      // 抽水  
$waterlevel = $water->SaveWaterLevel(); // 保存水位返回水位值  
$SL->SaveArrayWater($waterlevel);       // 存到备忘录  
$water->ShowWaterLevel();               // 展示水位  
<?php  
  
// Bucket 水桶类  
Class Bucket  
{  
    /** 
     * 水位值 
     * @var int 
     */  
    public $waterLevel;  
  
    /** 
     * 备忘录对象 
     * @var object 
     */  
    public $Memento;  
  
    /** 
     * 初始化水位值 
     * @access public  
     */  
    public function Initialize()  
    {  
        $this->waterLevel = 100;  
    }  
  
    /** 
     * 保存水位函数 
     * @access public  
     */  
    public function SaveWaterLevel()  
    {  
        // 查看保存备忘录对象是否存在  
        if($this->Memento)  
        {  
            // 调用保存备忘录函数  
            $levelwater = $this->Memento->SaveMemento($this->waterLevel);  
        }else{  
            $this->Memento = new SaveWaterMemento();  
            $levelwater = $this->Memento->SaveMemento($this->waterLevel);  
        }  
        return $levelwater;  
    }  
  
    /** 
     * 回退函数 
     * @access public  
     * @param  array $_Memento 参数名 
     */  
    public function RecoveryWaterLevel($_Memento)  
    {  
        if(count($_Memento) == 1)  
        {  
            $this->Initialize();  
        }  
        else{  
            $this->waterLevel = $_Memento[count($_Memento)-2];   
        }  
          
    }  
  
    /** 
     * 显示水位函数 
     * @access public  
     */  
    public function ShowWaterLevel()  
    {  
        echo "水位刻度为:{$this->waterLevel}L<br/>";  
    }  
  
    /** 
     * 抽水函数 
     * @access public  
     */  
    public function DrawOff()  
    {  
        $this->waterLevel -= 20;  
  
        if($this->waterLevel < 0)  
        {  
            echo "水已经放光了!---";  
            die;  
        }  
  
          
    }  
}  
  
// 保存水位备忘录类  
Class SaveWaterMemento  
{  
    /** 
     * 水位池 
     * @var array 
     */  
    public $waterLevel = array();  
  
    /** 
     * 水位池游标 
     * @var int 
     */  
    private $i = 0;  
  
    /** 
     * 回退函数 
     * @access public  
     * @param  int $_Memento 水位值 
     */  
    function SaveMemento($_WL)  
    {     
        $this->waterLevel[$this->i] = $_WL;  
        $this->i++;  
        return $this->waterLevel[$this->i-1];  
    }  
}  
  
// 保存水位类  
Class SaveWater  
{  
    /** 
     * 水位池 
     * @var array 
     */  
    public $memento = array();  
  
    /** 
     * 水位池游标 
     * @var int 
     */  
    private $i = 0;   
  
    /** 
     * 保存水位 
     * @access public  
     * @param  int $waterlevel 水位值 
     */  
    public function SaveArrayWater($waterlevel)  
    {  
        $this->memento[$this->i] = $waterlevel;  
        $this->i++;  
    }     
}  

输出结果:

水位刻度为:100L
----------------------第一次抽水----------------------
水位刻度为:80L
-----------------------回退一次----------------------
水位刻度为:100L
----------------------第二次抽水----------------------
水位刻度为:80L
----------------------第三次抽水----------------------
水位刻度为:60L
-----------------------回退一次----------------------
水位刻度为:80L
----------------------第四次抽水----------------------
水位刻度为:60L
----------------------第五次抽水----------------------
水位刻度为:40L

猜你喜欢

转载自blog.csdn.net/xhanguomzhu/article/details/79986489