Maison  >  Article  >  développement back-end  >  Parlons du mode mémo en PHP

Parlons du mode mémo en PHP

青灯夜游
青灯夜游avant
2021-07-20 19:25:152196parcourir

Dans l'article précédent "Analyse approfondie du modèle de générateur en PHP", nous avons présenté le modèle de générateur en PHP. Cet article vous amènera à comprendre le modèle de mémo dans le modèle de conception PHP.

Parlons du mode mémo en PHP

Mémo, le nom explique en fait sa fonction de manière très vivante. Un exemple typique est la fonction d'archive lorsque nous jouions à l'origine à des jeux sur disque dur. Lorsque vous vous inquiétez du grand BOSS que vous êtes sur le point d'affronter, vous enregistrez généralement d'abord une archive de progression. Si le défi échoue, vous pouvez lire directement l'archive pour restaurer l'état avant de défier le BOSS. Vous pourrez ensuite vous entraîner avec plaisir pendant un moment et revenir pour résoudre le grand BOSS. Cependant, juste au cas où, c'est toujours une bonne idée de sauvegarder un fichier avant de défier le BOSS. Un autre exemple est Git ou Svn, les outils de gestion de code que nous, programmeurs, utilisons quotidiennement. Chaque soumission est comme une sauvegarde d'archive. Lorsqu'il y a un problème avec le nouveau code, il suffit de revenir en arrière et de récupérer. Ce sont toutes des applications typiques du mode mémo. Examinons ensemble ce mode.

Diagramme de classe Gof et explication

Définition GoF : Capturez l'état interne d'un objet et enregistrez cet état à l'extérieur de l'objet sans détruire l'encapsulation. De cette façon, l'objet peut être restauré à son état d'origine enregistré à l'avenir

Diagramme de classes GoF :

Parlons du mode mémo en PHP

Implémentation du code :

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

L'auteur peut également être appelé l'initiateur. Il possède un état interne qui peut changer dans différentes circonstances. Lorsqu’un événement survient, cet état doit être restauré à son état d’origine. Ici, nous avons un CreateMemento() pour créer un mémo (archive) et un SetMeneto() pour restaurer l'état (lecture du fichier).

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

Memo, très simple, sert à enregistrer le statut. La sauvegarde de cet état sous la forme d'un objet permet à l'auteur de créer facilement de nombreuses archives pour enregistrer différents états.

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

Le responsable, également appelé classe manager, enregistre le mémo et le sort d'ici en cas de besoin. Il est uniquement responsable de la sauvegarde et ne peut pas modifier le mémo. Dans les applications complexes, cela peut être transformé en liste, tout comme un jeu qui peut afficher de manière sélective plusieurs enregistrements d'archives parmi lesquels les joueurs peuvent choisir.

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

Lors de l'appel du client, notre expéditeur a initialisé l'état et l'a enregistré, puis a artificiellement modifié l'état. À ce stade, il vous suffit de restaurer le statut par l'intermédiaire du responsable.

  • Pour parler franchement, le mode mémo consiste à laisser une classe externe B sauvegarder l'état interne de A, puis à restaurer facilement cet état au moment opportun.
  • Il existe en fait de nombreux scénarios d'application pour le mode mémo, tels que la restauration du navigateur, la sauvegarde et la restauration de la base de données, la sauvegarde et la restauration du système d'exploitation, l'annulation et la restauration de documents, les regrets des jeux d'échecs et de cartes, etc.
  • Ce mode peut conserver l'original Encapsulation du serveur, c'est-à-dire que ces états doivent être cachés aux objets externes, ils ne peuvent donc être transmis qu'à un objet mémo pour enregistrement
  • La copie des états entre l'expéditeur et le mémo peut entraîner des problèmes de performances, en particulier la complexité de objets volumineux L'état interne de l'ordinateur entraînera également des failles de codage, telles que l'absence de certains états. Avez-vous entendu parler de la fonction Time Machine de Mac, qui peut restaurer l'ordinateur à un état donné à un moment donné. En fait, Windows Ghost a également une fonction similaire. Notre système d'exploitation mobile a également décidé de développer une telle fonction. Lorsque nous cliquons sur Time Machine Backup, toutes les informations, données et informations d'état du téléphone seront compressées et enregistrées si l'utilisateur le permet, nous téléchargerons le package compressé sur notre serveur cloud pour éviter d'occuper la mémoire du téléphone de l'utilisateur. , il le sera. Il ne peut être enregistré que dans la mémoire du téléphone mobile de l'utilisateur. Lorsque le téléphone mobile de l'utilisateur doit être restauré à un certain moment, nous répertorierons toutes les sauvegardes de Time Machine. L'utilisateur peut restaurer l'état du système de téléphonie mobile à ce qu'il était à ce moment-là avec un simple clic de doigt. ce n'est pas très pratique ! !

Code complet : https://github.com/zhangyue0503/designpatterns-php/blob/master/17.memento/source/memento.php

Exemple

Cette fois, c'est retour à la messagerie texte. Voici un exemple. Habituellement, lorsque nous effectuons des fonctions d'envoi de SMS ou d'e-mails, il y aura une file d'attente pour lire le contenu à envoyer depuis la base de données ou le cache et l'envoyer en cas de succès, il sera ignoré. En cas d'échec, l'état du SMS sera ignoré. être changé en échec ou en ressentiment. Ici, nous le remettons directement à l'état non envoyé précédent, puis attendons que la prochaine file d'attente d'envoi effectue à nouveau l'envoi.

Diagramme des classes d'envoi de SMS

Code source complet : https://github.com/zhangyue0503/designpatterns-php/blob/master/17.memento/source/memento-message.phpParlons du mode mémo en PHP

<?php
class Message
{
    private $content;
    private $to;
    private $state;
    private $time;

    public function __construct($to, $content)
    {
        $this->to = $to;
        $this->content = $content;
        $this->state = &#39;未发送&#39;;
        $this->time = time();
    }

    public function Show()
    {
        echo $this->to, &#39;---&#39;, $this->content, &#39;---&#39;, $this->time, &#39;---&#39;, $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(&#39;手机号&#39; . $i, &#39;内容&#39; . $i);
    echo &#39;初始状态:&#39;;
    $m->Show();

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

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

    $mList[] = $m;
}

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

说明

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

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

作者:硬核项目经理

推荐学习:《PHP视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer