备忘录模式 Memento Pattern

未匹配的标注

定义

在不违背封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后恢复对象为先前的状态。

设计的原则和思想

  1. 解耦的是对象状态的历史记录和恢复。
  2. 不变部分是恢复,变化部分是对象状态。
  3. 核心思想是对象的备份与恢复。

一句话概括设计模式

把对象历史的状态保存起来,需要的时候可以恢复。

结构中包含的角色

  1. Originator(原发器)管理备忘录。
  2. Memento(备忘录) 存储内部状态。
  3. Caretaker(负责人) 存储备忘录。

最小可表达代码

// 备忘录管理者 (管理游戏进度的状态)
class Originator
{
    private $state;

    public function createMemento()
    {
        return new Memento($this);
    } 

    public function restoreMemento(Memento $m)
    {
        $this->state = $m->getState();
    }

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

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

// 备忘录 (记录游戏进度的信息)
class Memento
{  
    private $state;

    public function __construct(Originator $o)
    {  
        $this->state = $o->getState();
    }

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

//  归档备忘录 (存储游戏进度)
class Caretaker 
{
    private $memento;

    public function getMemento()
    {  
        return $this->memento;
    }

    public function setMemento(Memento $memento)
    {
        $this->memento = $memento;  
    }  
}

$originator = new Originator(); // 游戏进度管理类
$originator->setState("游戏存档10%"); // 现在的游戏进度
$careTaker = new CareTaker(); // 存档
$careTaker->setMemento($originator->createMemento());
$originator->setState("游戏存档30%"); // 现在的游戏进度
$originator->setState("游戏存档50%"); // 现在的游戏进度
$originator->restoreMemento($careTaker->getMemento()); // 突然想回到10%的时候
var_dump($originator->getState()); // 打印

优点

  1. 在不破坏对象封装的情况下创建对象状态快照。
  2. 可以方便地回到某个状态。

缺点

  1. 每一次保存对象状态都会消耗一定的内存,随着状态增多,消耗的内存也会逐渐增多。
  2. 对于大对象的备份来说,备份和恢复的耗时会比较长。

何时使用

  1. 需要保存/恢复数据的场景

实际应用场景

  1. 打游戏时的存档。
  2. Windows里的ctrl + z。
  3. 浏览器中的后退。
  4. 数据库的事务管理。
  5. 编辑器撤销与重做。
  6. 虚拟机生成快照与恢复。
  7. Git版本管理。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 0
发起讨论 只看当前版本


暂无话题~