簡介: 備忘錄模式,屬於行為型的設計模式。 在不破壞封裝性的前提下,捕獲一個對象的內部狀態,併在該對象之外保存這個狀態。這樣以後就可以將該對象恢復到原先保存的狀態。 備忘錄模式顧名思義,就是存檔功能,類似Git工具,每次提交都相當於一次備份。 主要有一下角色構成 Memento —— 負責存儲 Or ...
簡介:
備忘錄模式,屬於行為型的設計模式。
在不破壞封裝性的前提下,捕獲一個對象的內部狀態,併在該對象之外保存這個狀態。這樣以後就可以將該對象恢復到原先保存的狀態。
備忘錄模式顧名思義,就是存檔功能,類似Git工具,每次提交都相當於一次備份。
主要有一下角色構成
Memento —— 負責存儲 Originator 的 唯一內部狀態 ,它可以包含: string,number, array,類的實例等等。Memento 「不是公開的類」(任何人都不應該且不能更改它),並防止 Originator 以外的對象訪問它,它提供 2 個介面:Caretaker 只能看到備忘錄的窄介面,他只能將備忘錄傳遞給其他對象。Originator 卻可看到備忘錄的寬介面,允許它訪問返回到先前狀態所需要的所有數據。
Originator —— 它負責創建 Memento ,並記錄 外部對象當前時刻的狀態, 並可使用 Memento 恢復內部狀態。Originator 可根據需要決定 Memento 存儲 Originator 的哪些內部狀態。 Originator 也許(不是應該)有自己的方法(methods)。 但是,他們 不能更改已保存對象的當前狀態。
Caretaker —— 負責保存 Memento。 它可以修改一個對象;決定 Originator 中對象當前時刻的狀態; 從 Originator 獲取對象的當前狀態; 或者回滾 Originator 中對象的狀態。
適用場景:
任何撤銷操作的後悔藥,前提是有備份。
優點:
任何撤銷操作的後悔藥,前提是有備份。
缺點:
存檔的過程會帶來性能問題。
代碼:
//原發器,也可以叫做發起人。它有一個內部狀態(state),這個狀態可以在不同的情況下進行改變。當某一個事件發生時,需要將這個狀態恢復到原先的狀態。在這裡,我們有一個CreateMemento()用於創建一個備忘錄(存檔),有一個SetMeneto()用於還原狀態(讀檔)。
class Originator
{
private $state;
public function SetMeneto(Memento $m)
{
$this->state = $m->GetState();
}
public function CreateMemento()
{
$m = new Memento();
$m->SetState($this->state);
return $m;
}
public function SetState($state)
{
$this->state = $state;
}
public function ShowState()
{
echo $this->state, PHP_EOL;
}
}
//備忘錄,非常簡單,就是用於記錄狀態。將這個狀態以對象的形式保存,就可以讓原發器非常方便地創建很多存檔用於記錄各種不同的狀態。
class Memento
{
private $state;
public function SetState($state)
{
$this->state = $state;
}
public function GetState()
{
return $this->state;
}
}
//負責人,也叫做管理者類,保存備忘錄,當需要的時候從這裡取出備忘錄。它只負責保存,不能修改備忘錄。在複雜的應用中,可以將這裡做成列表,就像游戲中可以選擇性的展現多條存檔記錄供玩家選擇。
class Caretaker
{
private $memento;
public function SetMemento($memento)
{
$this->memento = $memento;
}
public function GetMemento()
{
return $this->memento;
}
}
//調用端==================================================
//客戶端的調用中,我們的原發器初始化狀態後進行了保存,然後人為的更改了狀態。這時只需要通過負責人將狀態還原回來就可以了。
$o = new Originator();
$o->SetState('狀態1');
$o->ShowState();
// 保存狀態
$c = new Caretaker();
$c->SetMemento($o->CreateMemento());
$o->SetState('狀態2');
$o->ShowState();
// 還原狀態
$o->SetMeneto($c->GetMemento());
$o->ShowState();