續上一篇:PHP行爲型設計模式(二),本文介紹第三類行爲型設計模式。javascript
類的狀態:php
備忘錄模式 (Memento Pattern): 在不破壞封閉的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態。這樣之後就可將該對象恢復到原先保存的狀態。又叫作快照模式(Snapshot Pattern)或Token模式java
(一)爲何須要備忘錄模式設計模式
1,有時一些發起人對象的內部信息必須保存在發起人對象之外的地方,可是必需要由發起人對象本身讀取,這時,使用備忘錄模式能夠把複雜的發起人內部信息對其餘的對象屏蔽起來,從而能夠恰當地保持封裝的邊界。數組
2,本模式簡化了發起人類。發起人再也不須要管理和保存其內部狀態的一個個版本,客戶端能夠自行管理他們所要的這些狀態的版本。微信
(二)備忘錄模式 UML圖post
(三)簡單實例學習
備忘錄模式往簡單了說,就是打副本。這裏咱們給出一個備忘錄模式的小例子,備份一個遊戲角色,也就是發起者的初始狀態,並恢復。ui
<?php
//發起人,所需備份者
class Originator{
//內部狀態
private $state;
//設置狀態
public function setState($state){
$this->state = $state ;
}
//查看狀態
public function getState(){
echo $this->state,PHP_EOL;
}
//建立一個備份錄
public function createMemento(){
return new Memento($this->state);
}
//恢復一個備份
public function restoreMemento(Memento $memento){
$this->state = $memento->getState();
}
}
//備忘錄角色
class Memento{
private $state; //用於存放發起人備份時的狀態
public function __construct($state){
$this->state = $state;
}
public function getState(){
return $this->state;
}
}
//備忘錄管理者
class Caretaker{
private $menento;
//存檔備忘錄
public function setMemento(Memento $memento){
$this->memento = $memento;
}
//取出備忘錄
public function getMemento(){
return $this->memento;
}
}
//實例化發起人 假如是個遊戲角色
$role = new Originator;
//設置狀態 滿血
$role->setState('滿血');
//備份
//建立備份錄管理者
$caretaker = new Caretaker;
//建立備份
$caretaker->setMemento($role->createMemento());
//狀態更改
$role->setState('死亡');
$role->getState();
//恢復備份
$role->restoreMemento($caretaker->getMemento());
//從新查看狀態
$role->getState();複製代碼
可能最後那段恢復備份的代碼有點繞,這是由於咱們引入了備份管理者。其實若是對於只有一個備份,那麼咱們也能夠不用備份管理者。而備份管理者存在的好處,固然是管理多個備份了。若是對於多個備份,咱們能夠把備份管理者的memento
屬性改成數組變量,就能夠存放多個備份了。this
其實備份在原型模式咱們也提過,咱們徹底能夠經過clone
關鍵字來備份,可是備忘錄模式相對於原型模式更精簡,可能有些時候咱們只想備份的就只有這一個屬性呢。並且從本質上說備忘錄模式恢復備份後仍是原來那個對象,而原型模式就不必定了。若是原型模式恢復備份是直接使用clone
出來的對象副本,那麼其實它就不算原來那個對象了,雖然它和被clone
的對象幾乎如出一轍,使用無差異,可是對於var_dump
,它的object#id
確定是不同的。
狀態模式 (State Pattern) :容許一個對象在其內部狀態改變時改變它的行爲,讓不一樣狀態的對象看起來彷佛修改了它的類,或者說是看起來不是來自同一個類。
(一)爲何須要狀態模式
1,將全部與某個狀態有關的行爲放到一個類中,而且能夠方便地增長新的狀態,只須要改變對象狀態便可改變對象的行爲。
2,本模式簡化了發起人類。發起人再也不須要管理和保存其內部狀態的一個個版本,客戶端能夠自行管理他們所要的這些狀態的版本。
(二)狀態模式 UML圖
(三)簡單實例
狀態模式一個最妙的應用就是經過變化狀態擁有不一樣的能力。好比咱們以水爲例,水若是是固態,那麼它就能融化成液態,若是是液態那麼它就能蒸發成氣態,而氣態也能凝華成固態。如今就讓咱們用程序來模擬這個過程。
<?php
//抽象狀態類
abstract class State{
abstract function handle(); } //固態 class Solid extends State{
public function handle(){
echo '固態 =>融化 =>液態轉化中'.PHP_EOL;
}
}
class Liquid extends State{
public function handle(){
echo '液態 =>蒸發 =>氣態轉化中'.PHP_EOL;
}
}
class Gas extends State{
public function handle(){
echo '氣態 =>凝華 =>固態轉化中'.PHP_EOL;
}
}
//context環境類 -----water
class Water{
protected $states = array();
protected $current=0;
public function __construct() {
$this->states[]=new Solid;
$this->states[]=new Liquid;
$this->states[]=new Gas;
}
//水的變化
public function change(){
//告知當前狀態
echo '當前所處狀態'.get_Class($this->states[$this->current]).PHP_EOL;
//當前狀態能力
$this->states[$this->current]->handle();
//狀態變化
$this->changeState();
}
//狀態變化
public function changeState() {
$this->current++ == 2 && $this->current = 0;
}
}
//實例化具體環境角色-----水
$water = new Water;
//水的能力變化 ---與它的狀態相關
$water->change();
$water->change();
$water->change();
$water->change();複製代碼
固然咱們這裏只是一個簡單的示例,你徹底可讓一個狀態有多個能力,或者經過給water
給一個對外的接口,經過傳參使其轉化爲你指定的狀態。
上一篇::PHP行爲型設計模式(二)
感謝閱讀,因爲筆者也是初學設計模式,能力有限,文章不可避免地有失偏頗
後續更新 PHP行爲型設計模式(四)介紹,歡迎你們評論指正
我最近的學習總結: