行为型设计模式 - 备忘录 Memento
作者:菜皮日记
- 2023-09-08 北京
本文字数:2688 字
阅读完需:约 9 分钟
简介
允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态,该状态保存在对象之外,这样就可以不破坏原有对象的封装性了。
角色
Originator 原发器
即需要被保存状态的类
抽象 Memento 备忘录类
定义备忘录基本接口
可以看做成是快照 Snapshot
具体 Memento 备忘录类
实现接口
Caretaker 负责人
即连接 Originator 和 Memento 的类,维护一个 Memento 队列,通过操作队列实现 undo redo 的操作
类图
图中,ConcreteOriginator 通过 save 方法,生成一个 Memento,Caretaker 的 history 属性保存这些 Memento,实现 undo 操作。
类图
代码
class Originator{ private $state;
public function __construct(string $state) { $this->state = $state; echo "Originator: My initial state is: {$this->state}\n"; }
public function doSomething(): void { echo "Originator: I'm doing something important.\n"; $this->state = $this->generateRandomString(30); echo "Originator: and my state has changed to: {$this->state}\n"; }
private function generateRandomString(int $length = 10): string { return substr( str_shuffle( str_repeat( $x = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length / strlen($x)) ) ), 1, $length ); }
public function save(): Memento { return new ConcreteMemento($this->state); }
public function restore(Memento $memento): void { $this->state = $memento->getState(); echo "Originator: My state has changed to: {$this->state}\n"; }}
interface Memento{ public function getName(): string;
public function getDate(): string;}
class ConcreteMemento implements Memento{ private $state;
private $date;
public function __construct(string $state) { $this->state = $state; $this->date = date('Y-m-d H:i:s'); }
public function getState(): string { return $this->state; }
public function getName(): string { return $this->date . " / (" . substr($this->state, 0, 9) . "...)"; }
public function getDate(): string { return $this->date; }}
class Caretaker{ private $mementos = [];
private $originator;
public function __construct(Originator $originator) { $this->originator = $originator; }
public function backup(): void { echo "\nCaretaker: Saving Originator's state...\n"; $this->mementos[] = $this->originator->save(); }
public function undo(): void { if (!count($this->mementos)) { return; } $memento = array_pop($this->mementos);
echo "Caretaker: Restoring state to: " . $memento->getName() . "\n"; try { $this->originator->restore($memento); } catch (\Exception $e) { $this->undo(); } }
public function showHistory(): void { echo "Caretaker: Here's the list of mementos:\n"; foreach ($this->mementos as $memento) { echo $memento->getName() . "\n"; } }}
$originator = new Originator("Super-duper-super-puper-super.");$caretaker = new Caretaker($originator);
$caretaker->backup();$originator->doSomething();
$caretaker->backup();$originator->doSomething();
$caretaker->backup();$originator->doSomething();
echo "\n";$caretaker->showHistory();
echo "\nClient: Now, let's rollback!\n\n";$caretaker->undo();
echo "\nClient: Once more!\n\n";$caretaker->undo();
复制代码
output:
Originator: My initial state is: Super-duper-super-puper-super.
Caretaker: Saving Originator's state...Originator: I'm doing something important.Originator: and my state has changed to: uDdcJyRkbMEFqaKnpHiYQtrzWjXPVI
Caretaker: Saving Originator's state...Originator: I'm doing something important.Originator: and my state has changed to: YrymDJvtFqlwGpMuCNXadsQonIVPzR
Caretaker: Saving Originator's state...Originator: I'm doing something important.Originator: and my state has changed to: pOuLBUelsmFRkKrbhAGfqzTtQXjnNH
Caretaker: Here's the list of mementos:2023-06-28 01:51:01 / (Super-dup...)2023-06-28 01:51:01 / (uDdcJyRkb...)2023-06-28 01:51:01 / (YrymDJvtF...)
Client: Now, let's rollback!
Caretaker: Restoring state to: 2023-06-28 01:51:01 / (YrymDJvtF...)Originator: My state has changed to: YrymDJvtFqlwGpMuCNXadsQonIVPzR
Client: Once more!
Caretaker: Restoring state to: 2023-06-28 01:51:01 / (uDdcJyRkb...)Originator: My state has changed to: uDdcJyRkbMEFqaKnpHiYQtrzWjXPVI
复制代码
划线
评论
复制
发布于: 刚刚阅读数: 4
菜皮日记
关注
全干程序员 2018-08-08 加入
还未添加个人简介










评论