备忘录模式 Memento Pattern
定义
在不违背封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后恢复对象为先前的状态。
设计的原则和思想
- 解耦的是对象状态的历史记录和恢复。
 - 不变部分是恢复,变化部分是对象状态。
 - 核心思想是对象的备份与恢复。
 
一句话概括设计模式
把对象历史的状态保存起来,需要的时候可以恢复。
结构中包含的角色
- Originator(原发器)管理备忘录。
 - Memento(备忘录) 存储内部状态。
 - 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()); // 打印
优点
- 在不破坏对象封装的情况下创建对象状态快照。
 - 可以方便地回到某个状态。
 
缺点
- 每一次保存对象状态都会消耗一定的内存,随着状态增多,消耗的内存也会逐渐增多。
 - 对于大对象的备份来说,备份和恢复的耗时会比较长。
 
何时使用
- 需要保存/恢复数据的场景
 
实际应用场景
- 打游戏时的存档。
 - Windows里的ctrl + z。
 - 浏览器中的后退。
 - 数据库的事务管理。
 - 编辑器撤销与重做。
 - 虚拟机生成快照与恢复。
 - Git版本管理。
 
          
99+种软件模式
                    
                    
            
            
                关于 LearnKu
              
                    
                    
                    
 
推荐文章: