它提供了在不破坏封装(对象不须要具备返回当前状态的函数)的状况下恢复到以前状态(使用回滚)或者获取对象的内部状态。php
备忘录模式使用 3 个类来实现:Originator,Caretaker 和 Memento。laravel
Memento —— 负责存储 Originator 的 惟一内部状态 ,它能够包含: string,number, array,类的实例等等。Memento 「不是公开的类」(任何人都不该该且不能更改它),并防止 Originator 之外的对象访问它,它提供 2 个接口:Caretaker 只能看到备忘录的窄接口,他只能将备忘录传递给其余对象。Originator 却可看到备忘录的宽接口,容许它访问返回到先前状态所须要的全部数据。面试
Originator —— 它负责建立 Memento ,并记录 外部对象当前时刻的状态, 并可以使用 Memento 恢复内部状态。Originator 可根据须要决定 Memento 存储 Originator 的哪些内部状态。 Originator 也许(不是应该)有本身的方法(methods)。 可是,他们 不能更改已保存对象的当前状态。sql
Caretaker —— 负责保存 Memento。 它能够修改一个对象;决定 Originator 中对象当前时刻的状态; 从 Originator 获取对象的当前状态; 或者回滚 Originator 中对象的状态。shell
保存以前控制 ORM Model 中的状态设计模式
并将这个随机数存在时序机中服务器
发送一个随机数架构
<?php namespace DesignPatterns\Behavioral\Memento; class Memento { /** * @var State */ private $state; /** * @param State $stateToSave */ public function __construct(State $stateToSave) { $this->state = $stateToSave; } /** * @return State */ public function getState() { return $this->state; } }
<?php namespace DesignPatterns\Behavioral\Memento; class State { const STATE_CREATED = 'created'; const STATE_OPENED = 'opened'; const STATE_ASSIGNED = 'assigned'; const STATE_CLOSED = 'closed'; /** * @var string */ private $state; /** * @var string[] */ private static $validStates = [ self::STATE_CREATED, self::STATE_OPENED, self::STATE_ASSIGNED, self::STATE_CLOSED, ]; /** * @param string $state */ public function __construct(string $state) { self::ensureIsValidState($state); $this->state = $state; } private static function ensureIsValidState(string $state) { if (!in_array($state, self::$validStates)) { throw new \InvalidArgumentException('Invalid state given'); } } public function __toString(): string { return $this->state; } }
<?php namespace DesignPatterns\Behavioral\Memento; /** * Ticket 是 Originator 的原始副本 */ class Ticket { /** * @var State */ private $currentState; public function __construct() { $this->currentState = new State(State::STATE_CREATED); } public function open() { $this->currentState = new State(State::STATE_OPENED); } public function assign() { $this->currentState = new State(State::STATE_ASSIGNED); } public function close() { $this->currentState = new State(State::STATE_CLOSED); } public function saveToMemento(): Memento { return new Memento(clone $this->currentState); } public function restoreFromMemento(Memento $memento) { $this->currentState = $memento->getState(); } public function getState(): State { return $this->currentState; } }
<?php namespace DesignPatterns\Behavioral\Memento\Tests; use DesignPatterns\Behavioral\Memento\State; use DesignPatterns\Behavioral\Memento\Ticket; use PHPUnit\Framework\TestCase; class MementoTest extends TestCase { public function testOpenTicketAssignAndSetBackToOpen() { $ticket = new Ticket(); // 打开 ticket $ticket->open(); $openedState = $ticket->getState(); $this->assertEquals(State::STATE_OPENED, (string) $ticket->getState()); $memento = $ticket->saveToMemento(); // 分配 ticket $ticket->assign(); $this->assertEquals(State::STATE_ASSIGNED, (string) $ticket->getState()); // 如今已经恢复到已打开的状态,但须要验证是否已经克隆了当前状态做为副本 $ticket->restoreFromMemento($memento); $this->assertEquals(State::STATE_OPENED, (string) $ticket->getState()); $this->assertNotSame($openedState, $ticket->getState()); } }
PHP 互联网架构师 50K 成长指南+行业问题解决总纲(持续更新)
面试10家公司,收获9个offer,2020年PHP 面试问题
★若是喜欢个人文章,想与更多资深开发者一块儿交流学习的话,获取更多大厂面试相关技术咨询和指导,欢迎加入咱们的群啊,暗号:phpzh(君羊号码856460874)。
内容不错的话但愿你们支持鼓励下点个赞/喜欢,欢迎一块儿来交流;另外若是有什么问题 建议 想看的内容能够在评论提出