首页 > 其他分享 >行为型设计模式-备忘录 Memento

行为型设计模式-备忘录 Memento

时间:2023-09-07 13:35:59浏览次数:40  
标签:Originator function Caretaker 备忘录 state 设计模式 public Memento

简介

允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态,该状态保存在对象之外,这样就可以不破坏原有对象的封装性了。

角色

  • Originator 原发器

    即需要被保存状态的类

  • 抽象 Memento 备忘录类

    定义备忘录基本接口

    可以看做成是快照 Snapshot

  • 具体 Memento 备忘录类

    实现接口

  • Caretaker 负责人

    即连接Originator和Memento的类,维护一个Memento队列,通过操作队列实现undo redo的操作

类图

图中,ConcreteOriginator通过save方法,生成一个Memento,Caretaker 的history属性保存这些Memento,实现undo操作。

类图

代码

class Originator
{
    private $state;

    public function __construct(string $state)
    {
        $this->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
        );
    }

    public function save(): Memento
    {
        return new ConcreteMemento($this->state);
    }

    public function restore(Memento $memento): void
    {
        $this->state = $memento->getState();
        echo "Originator: My state has changed to: {$this->state}\n";
    }
}

interface Memento
{
    public function getName(): string;

    public function getDate(): string;
}

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');
    }

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

    public function getName(): string
    {
        return $this->date . " / (" . substr($this->state, 0, 9) . "...)";
    }

    public function getDate(): string
    {
        return $this->date;
    }
}

class Caretaker
{
    private $mementos = [];

    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";
        }
    }
}

$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();

output:

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: uDdcJyRkbMEFqaKnpHiYQtrzWjXPVI

Caretaker: Saving Originator's state...
Originator: I'm doing something important.
Originator: and my state has changed to: YrymDJvtFqlwGpMuCNXadsQonIVPzR

Caretaker: Saving Originator's state...
Originator: I'm doing something important.
Originator: and my state has changed to: pOuLBUelsmFRkKrbhAGfqzTtQXjnNH

Caretaker: Here's the list of mementos:
2023-06-28 01:51:01 / (Super-dup...)
2023-06-28 01:51:01 / (uDdcJyRkb...)
2023-06-28 01:51:01 / (YrymDJvtF...)

Client: Now, let's rollback!

Caretaker: Restoring state to: 2023-06-28 01:51:01 / (YrymDJvtF...)
Originator: My state has changed to: YrymDJvtFqlwGpMuCNXadsQonIVPzR

Client: Once more!

Caretaker: Restoring state to: 2023-06-28 01:51:01 / (uDdcJyRkb...)
Originator: My state has changed to: uDdcJyRkbMEFqaKnpHiYQtrzWjXPVI

本文由mdnice多平台发布

标签:Originator,function,Caretaker,备忘录,state,设计模式,public,Memento
From: https://www.cnblogs.com/caipi/p/17684582.html

相关文章

  • 行为型设计模式-状态 State
    简介跟状态机密切相关。有限状态机FSM包含状态、事件、动作三个元素。当发生一个事件时,引发老状态变成新状态,并执行一个动作。状态和行为间一般是有限制的,如某些行为只能再某些状态下进行,某些状态只能触发某些行为。简单的状态间转换可使用ifelse。更有条理的可以用查表......
  • 行为型设计模式-策略 Strategy
    简介一组实现了同一个策略接口的策略,可以随时指定用哪一种策略完成业务。策略模式其实跟桥接模式很像,都是通过持有另一个对象,达到组合的效果。角色Context上下文可设置使用的Strategy抽象Strategy具体Strategy类图如图,Context使用setStrategy方法设置当前使......
  • 行为型设计模式-模板方法 Template Method
    简介父类抽象类定义大的处理流程,部分细节做成抽象方法,留给子类去实现。如Java的JUnit中,setUptearDown方法都是留给具体的测试用例来写,Servlet中service处理了一个请求的大部分工作,留下doGet和doPost给业务自定义处理。另外callback一般分两种方式:同步回调、异步回调,其中同步......
  • 设计模式——建造者模式
    建造者模式简介1.建造者模式适用于一个具有较多的零件的复杂产品的创建过程,由于需求的变化,组成这个复杂产品的各个零件经常猛烈变化,但是他们的组合方式却相对稳定。他可以使你分步骤创建复杂的对象。建造者模式解决的问题一般当我们遇到一个非常复杂的对象的时候,这个对象里面有......
  • Java设计模式-懒汉模式
    懒汉模式(LazyInitialization)是一种创建型设计模式,它用于在需要时才创建对象。这种模式的主要优点是节省资源,因为它只在真正需要对象时才创建实例。在Java中,懒汉模式可以通过使用静态内部类实现。以下是一个简单的Java懒汉模式示例:publicclassLazySingleton{//创建一个静......
  • 设计模式-建造者模式
    建造者模式是一种创建型的设计模式,将一个对象的创建过程拆分成一个个小的部分,每次决定其中的一个细节,构建出一个复杂对象对象的创建过程被拉长分散,可能会经历一系列的复杂决策,最终才会形成我们需要的对象对象拥有多个参数,或者拥有包含多个参数的构造函数,通过建造......
  • 结构型设计模式-组合(对象树) Composite
    简介组合模式又叫对象树,将对象按照树形结构串起来,呈现出局部和整体相同的特性。树中每个节点都由两部分组成,首先节点有自己的业务数据,其次节点内可以含有子节点集合。比如盒子中可以放物品,也可以放其他小盒子,小盒子里又可以放物品和其他更小的盒子。当计算盒子的物品价格时,只......
  • 结构型设计模式-桥接(模块化) Bridge
    简介桥接模式可将一系列紧密相关的、水平等级的类,转变为组合关系,形成垂直等级关系。如抽象类Color、Shape,分别有RedColor、BlueColor、CircleShape、SquareShape的实现类,那么想创建红色方形,则可以将Shape类中持有Color引用,动态向Shape中注入Color实现即可。否则分别......
  • 结构型设计模式-适配器 Adapter
    结构型设计模式-适配器Adapterdate:April13,2021slug:design-pattern-adapterstatus:Publishedtags:设计模式type:Page简介适配器模式是一种结构型设计模式,它能使接口不兼容的对象能够相互合作角色Client接口/Target目标接口用户使用的接口Adaptee被......
  • 创建型设计模式-原型 Prototype
    简介原型模式支持按照一个对象为模板,创建出另一个一模一样的对象。简单说就是把A对象的属性,都赋值到B上,注意必须是深拷贝,即clone后的AB关联的对象是不同的对象。角色抽象原型类定义clone方法具体实现类实现clone方法类图代码classPrototype{p......