PHP开发PHP经验分享

编程中的设计模式之备忘录模式

2020-10-10  本文已影响0人  phpworkerman
定义

备忘录模式(Memento Pattern)是在不破坏封装的前提下,捕获一个对象的内部状态并在该对象之外保存,存储这个状态的对象就是备忘录,可以用来恢复对象之前的状态。

代码示例

现有发起者Originator 可以修改status状态,Memento 用来存储发状态,Caretker 用来管理备忘录。Originator 拥有对备忘录的读取和写入权限,Caretker 只拥有管理备忘录的权限,不能直接访问备忘录内容,Caretker 的意义在于可同时存储多种状态。

<?php
class Memento
{
    private $originator;

    public function __construct($originator)
    {
        $this->originator = $originator;
    }

    public function get()
    {
        return $this->originator;
    }
}

class Originator
{
    private $status;
    private $memento;

    public function setState($status)
    {
        $this->status = $status;
    }

    public function getState()
    {
        return $this->status;
    }

    public function saveStateToMemento()
    {
        return new Memento($this->status);
    }

    public function getStateFromMemento($memento)
    {
        return $memento->get();
    }
}

class Caretaker
{
    public $mementoList = [];

    public function setMemento($memento)
    {
        $this->mementoList[] = $memento;
    }

    public function get($index)
    {
        return $this->mementoList[$index];
    }
}

class DemoPattern
{
    public function handle()
    {
        $originator = new Originator;
        $originator->setState('pending');
        echo $originator->getState() . '<br>';

        $caretaker = new Caretaker();
        $caretaker->setMemento($originator->saveStateToMemento());

        $originator->setState('processing');
        $caretaker->setMemento($originator->saveStateToMemento());
        echo $originator->getState() . '<br>';

        $originator->setState('completed');
        $caretaker->setMemento($originator->saveStateToMemento());
        echo $originator->getState() . '<br>';

        $pending = $caretaker->get(0);
        $memento = $originator->getStateFromMemento($pending);
        echo '还原第一版状态:' . $memento;
    }
}

$demoPattern = new DemoPattern;
$demoPattern->handle();
总结

备忘录模式可以让对象有选择性的保存属性,外部可以执行恢复的操作,但是不会暴露实现的细节,配合备忘录管理器可以方便的实现多版本的任意回滚,但是备忘录模式也有缺点,如果需要备份的对象属性非常大,会很消耗系统资源,所以只在关键位置使用备忘录模式。

上一篇 下一篇

猜你喜欢

热点阅读