php 示例
最后更新于:2022-04-02 04:21:05
[TOC]
## 示例
**使用示例:** 备忘录模式在 PHP 中的实际应用非常值得怀疑。在大部分情况下,你只需简单地使用序列化就能轻松生成对象的副本。
### 概念示例
输出 ``` 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: srGIngezAEboNPDjBkuvymJKUtMSFX Caretaker: Saving Originator's state... Originator: I'm doing something important. Originator: and my state has changed to: UwCZQaHJOiERLlchyVuMbXNtpqTgWF Caretaker: Saving Originator's state... Originator: I'm doing something important. Originator: and my state has changed to: incqsdoJXkbDUuVOvRFYyKBgfzwZCQ Caretaker: Here's the list of mementos: 2018-06-04 14:50:39 / (Super-dup...) 2018-06-04 14:50:39 / (srGIngezA...) 2018-06-04 14:50:39 / (UwCZQaHJO...) Client: Now, let's rollback! Caretaker: Restoring state to: 2018-06-04 14:50:39 / (UwCZQaHJO...) Originator: My state has changed to: UwCZQaHJOiERLlchyVuMbXNtpqTgWF Client: Once more! Caretaker: Restoring state to: 2018-06-04 14:50:39 / (srGIngezA...) Originator: My state has changed to: srGIngezAEboNPDjBkuvymJKUtMSFX ```
';
main.php
``` 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, ); } /** * Saves the current state inside a memento. */ public function save(): Memento { return new ConcreteMemento($this->state); } /** * Restores the Originator's state from a memento object. * @param Memento $memento */ public function restore(Memento $memento): void { $this->state = $memento->getState(); echo "Originator: My state has changed to: {$this->state}\n"; } } /** * The Memento interface provides a way to retrieve the memento's metadata, such * as creation date or name. However, it doesn't expose the Originator's state. */ interface Memento { public function getName(): string; public function getDate(): string; } /** * The Concrete Memento contains the infrastructure for storing the Originator's * state. */ 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'); } /** * The Originator uses this method when restoring its state. */ public function getState(): string { return $this->state; } /** * The rest of the methods are used by the Caretaker to display metadata. */ public function getName(): string { return $this->date . " / (" . substr($this->state, 0, 9) . "...)"; } public function getDate(): string { return $this->date; } } // 看守 class Caretaker { /** * @var Memento[] */ private $mementos = []; /** * @var Originator */ 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"; } } } /** * Client code. */ $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(); ```输出 ``` 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: srGIngezAEboNPDjBkuvymJKUtMSFX Caretaker: Saving Originator's state... Originator: I'm doing something important. Originator: and my state has changed to: UwCZQaHJOiERLlchyVuMbXNtpqTgWF Caretaker: Saving Originator's state... Originator: I'm doing something important. Originator: and my state has changed to: incqsdoJXkbDUuVOvRFYyKBgfzwZCQ Caretaker: Here's the list of mementos: 2018-06-04 14:50:39 / (Super-dup...) 2018-06-04 14:50:39 / (srGIngezA...) 2018-06-04 14:50:39 / (UwCZQaHJO...) Client: Now, let's rollback! Caretaker: Restoring state to: 2018-06-04 14:50:39 / (UwCZQaHJO...) Originator: My state has changed to: UwCZQaHJOiERLlchyVuMbXNtpqTgWF Client: Once more! Caretaker: Restoring state to: 2018-06-04 14:50:39 / (srGIngezA...) Originator: My state has changed to: srGIngezAEboNPDjBkuvymJKUtMSFX ```