0

0

一起聊聊PHP中的备忘录模式

青灯夜游

青灯夜游

发布时间:2021-07-20 19:25:15

|

2375人浏览过

|

来源于掘金--硬核项目经理

转载

在之前的文章《深入浅析php中的建造者模式》中我们介绍了php中的建造者模式,下面本篇文章带大家了解一下php设计模式中的备忘录模式。

一起聊聊PHP中的备忘录模式

备忘录,这个名字其实就已经很形象的解释了它的作用。典型的例子就是我们原来玩硬盘游戏时的存档功能。当你对即将面对的大BOSS有所顾虑时,一般都会先保存一次进度存档。如果挑战失败了,直接读取存档就可以恢复到挑战BOSS前的状态,然后你就开开心心的再去练一会级回来解决这个大BOSS就好了。不过,为了以防万一,在挑战BOSS之前存个档总是好的。另外一个例子就是我们码农们天天要用到的代码管理工具Git或者Svn了。每次的提交都像是一次存档备份,当新代码出现问题的时候,直接回滚恢复就行了。这些,都是备忘录模式的典型应用,下面就一起来看看这个模式吧。

Gof类图及解释

GoF定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态

GoF类图:

立即学习PHP免费学习笔记(深入)”;

1.png

代码实现:

class Originator
{
    private $state;
    public function SetMeneto(Memento $m)
    {
        $this->state = $m->GetState();
    }
    public function CreateMemento()
    {
        $m = new Memento();
        $m->SetState($this->state);
        return $m;
    }

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

    public function ShowState()
    {
        echo $this->state, PHP_EOL;
    }
}

原发器,也可以叫做发起人。它有一个内部状态(state),这个状态可以在不同的情况下进行改变。当某一个事件发生时,需要将这个状态恢复到原先的状态。在这里,我们有一个CreateMemento()用于创建一个备忘录(存档),有一个SetMeneto()用于还原状态(读档)。

class Memento
{
    private $state;
    public function SetState($state)
    {
        $this->state = $state;
    }
    public function GetState()
    {
        return $this->state;
    }
}

备忘录,非常简单,就是用于记录状态。将这个状态以对象的形式保存,就可以让原发器非常方便地创建很多存档用于记录各种不同的状态。

class Caretaker
{
    private $memento;
    public function SetMemento($memento)
    {
        $this->memento = $memento;
    }
    public function GetMemento()
    {
        return $this->memento;
    }
}

负责人,也叫做管理者类,保存备忘录,当需要的时候从这里取出备忘录。它只负责保存,不能修改备忘录。在复杂的应用中,可以将这里做成列表,就像游戏中可以选择性的展现多条存档记录供玩家选择。

$o = new Originator();
$o->SetState('状态1');
$o->ShowState();

// 保存状态
$c = new Caretaker();
$c->SetMemento($o->CreateMemento());

$o->SetState('状态2');
$o->ShowState();

// 还原状态
$o->SetMeneto($c->GetMemento());
$o->ShowState();

客户端的调用中,我们的原发器初始化状态后进行了保存,然后人为的更改了状态。这时只需要通过负责人将状态还原回来就可以了。

DM建站系统家电设备维修服务机构网站模板1.22
DM建站系统家电设备维修服务机构网站模板1.22

这是一款DM建站系统家电设备维修服务机构网站模板,DM企业建站系统。是由php+mysql开发的一套专门用于中小企业网站建设的开源cms。DM系统的理念就是组装,把模板和区块组装起来,产生不同的网站效果。可以用来快速建设一个响应式的企业网站( PC,手机,微信都可以访问)。后台操作简单,维护方便。DM企业建站系统安装步骤:第一步,先用phpmyadmin导入sql文件。 第二步:把文件放到你的本地

下载
  • 备忘录模式说白了就是让一个外部类B来保存A的内部状态,然后在适当的时候可以方便的还原这个状态。
  • 备忘录模式的应用场景其实非常多,浏览器的回退、数据库的备份还原、操作系统的备份还原、文档的撤销重做、棋牌游戏的悔棋等等
  • 这个模式能够保持对原发器的封装,也就是这些状态需要对外部的对象隐藏,所以只能交给一个备忘录对象来记录
  • 状态在原发器和备忘录之间的拷贝可能带来性能问题,特别是大型对象的复杂繁多的内部状态,而且也会带来一些编码方面的漏洞,比如漏掉某些状态

Mac的时光机功能大家有了解过吧,可以将电脑恢复到某一时间点的状态下。其实windows的ghost也是类似的功能。我们的手机操作系统上也决定开发这样的一个功能。当我们点击时光机备份时,将手机上所有的资料、数据、状态信息都压缩保存起来,如果用户允许的话,我们将这个压缩包上传到我们的云服务器上避免占用用户的手机内存,否则就只能保存到用户的手机内存中了。当用户的手机需要恢复到某个时间点,我们将所有的时光机备份列出,用户只需要用手指轻轻一按就可以把手机系统状态恢复到当时的样子了,是不是非常方便!!

完整代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/17.memento/source/memento.php

实例

这次又回到短信发送的例子上来。通常我们做短信或者邮件发送这些功能时,会有一个队列从数据库或者缓存中读取要发送的内容进行发送,如果成功了就不管了,如果失败了会将短信的状态改成失败或者重发。在这里,我们直接将它改回到之前未发送的状态然后等待下次发送的队列再次执行发送。

短信发送类图

2.png

完整源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/17.memento/source/memento-message.php

to = $to;
        $this->content = $content;
        $this->state = '未发送';
        $this->time = time();
    }

    public function Show()
    {
        echo $this->to, '---', $this->content, '---', $this->time, '---', $this->state, PHP_EOL;
    }

    public function CreateSaveSate()
    {
        $ss = new SaveState();
        $ss->SetState($this->state);
        return $ss;
    }

    public function SetSaveState($ss)
    {
        if ($this->state != $ss->GetState()) {
            $this->time = time();
        }
        $this->state = $ss->GetState();
    }

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

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

}

class SaveState
{
    private $state;
    public function SetState($state)
    {
        $this->state = $state;
    }
    public function GetState()
    {
        return $this->state;
    }
}

class StateContainer
{
    private $ss;
    public function SetSaveState($ss)
    {
        $this->ss = $ss;
    }
    public function GetSaveState()
    {
        return $this->ss;
    }
}

// 模拟短信发送
$mList = [];
$scList = [];
for ($i = 0; $i < 10; $i++) {
    $m = new Message('手机号' . $i, '内容' . $i);
    echo '初始状态:';
    $m->Show();

    // 保存初始信息
    $sc = new StateContainer();
    $sc->SetSaveState($m->CreateSaveSate());
    $scList[] = $sc;

    // 模拟短信发送,2发送成功,3发送失败
    $pushState = mt_rand(2, 3);
    $m->SetState($pushState == 2 ? '发送成功' : '发送失败');
    echo '发布后状态:';
    $m->Show();

    $mList[] = $m;
}

// 模拟另一个线程查找发送失败的并把它们还原到未发送状态
sleep(2);
foreach ($mList as $k => $m) {
    if ($m->GetState() == '发送失败') { // 如果是发送失败的,还原状态
        $m->SetSaveState($scList[$k]->GetSaveState());
    }
    echo '查询发布失败后状态:';
    $m->Show();
}

说明

  • 短信类做为我们的原发器,在发送前就保存了当前的发送状态
  • 随机模拟短信发送,只有两个状态,发送成功或者失败,并改变原发器的状态为成功或者失败
  • 模拟另一个线程或者脚本对短信的发送状态进行检查,如果发现有失败的,就将它重新改回未发送的状态
  • 这里我们只是保存了发送状态这一个字段,其他原发器的内部属性并没有保存
  • 真实的场景下我们应该会有一个重试次数的限制,当超过这个次数后,状态改为彻底的发送失败,不再进行重试了

原文地址:https://juejin.cn/post/6844903983555805192

作者:硬核项目经理

推荐学习:《PHP视频教程

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

11

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

4

2026.01.21

无人机驾驶证报考 uom民用无人机综合管理平台官网
无人机驾驶证报考 uom民用无人机综合管理平台官网

无人机驾驶证(CAAC执照)报考需年满16周岁,初中以上学历,身体健康(矫正视力1.0以上,无严重疾病),且无犯罪记录。个人需通过民航局授权的训练机构报名,经理论(法规、原理)、模拟飞行、实操(GPS/姿态模式)及地面站训练后考试合格,通常15-25天拿证。

16

2026.01.21

Python多线程合集
Python多线程合集

本专题整合了Python多线程相关教程,阅读专题下面的文章了解更多详细内容。

1

2026.01.21

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

4

2026.01.21

windows激活码分享 windows一键激活教程指南
windows激活码分享 windows一键激活教程指南

Windows 10/11一键激活可以通过PowerShell脚本或KMS工具实现永久或长期激活。最推荐的简便方法是打开PowerShell(管理员),运行 irm https://get.activated.win | iex 脚本,按提示选择数字激活(选项1)。其他方法包括使用HEU KMS Activator工具进行智能激活。

2

2026.01.21

excel表格操作技巧大全 表格制作excel教程
excel表格操作技巧大全 表格制作excel教程

Excel表格操作的核心技巧在于 熟练使用快捷键、数据处理函数及视图工具,如Ctrl+C/V(复制粘贴)、Alt+=(自动求和)、条件格式、数据验证及数据透视表。掌握这些可大幅提升数据分析与办公效率,实现快速录入、查找、筛选和汇总。

6

2026.01.21

毒蘑菇显卡测试网站入口 毒蘑菇测试官网volumeshader_bm
毒蘑菇显卡测试网站入口 毒蘑菇测试官网volumeshader_bm

毒蘑菇VOLUMESHADER_BM测试网站网址为https://toolwa.com/vsbm/,该平台基于WebGL技术通过渲染高复杂度三维分形图形评估设备图形处理能力,用户可通过拖动彩色物体观察画面流畅度判断GPU与CPU协同性能;测试兼容多种设备,但中低端手机易卡顿或崩溃,高端机型可能因发热降频影响表现,桌面端需启用独立显卡并使用支持WebGL的主流浏览器以确保准确结果

25

2026.01.21

github中文官网入口 github中文版官网网页进入
github中文官网入口 github中文版官网网页进入

github中文官网入口https://docs.github.com/zh/get-started,GitHub 是一种基于云的平台,可在其中存储、共享并与他人一起编写代码。 通过将代码存储在GitHub 上的“存储库”中,你可以: “展示或共享”你的工作。 持续“跟踪和管理”对代码的更改。

7

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 9.1万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 9.5万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号