备忘录模式(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