Heim  >  Artikel  >  Backend-Entwicklung  >  Lassen Sie uns über den Memo-Modus in PHP sprechen

Lassen Sie uns über den Memo-Modus in PHP sprechen

青灯夜游
青灯夜游nach vorne
2021-07-20 19:25:152196Durchsuche

Im vorherigen Artikel „Eingehende Analyse des Builder-Musters in PHP“ haben wir das Builder-Muster in PHP vorgestellt. Dieser Artikel führt Sie zum Verständnis des Memo-Musters im PHP-Designmuster.

Lassen Sie uns über den Memo-Modus in PHP sprechen

Memo, der Name erklärt seine Funktion tatsächlich sehr anschaulich. Ein typisches Beispiel ist die Archivfunktion, als wir ursprünglich Festplattenspiele spielten. Wenn Sie sich Sorgen über den großen BOSS machen, dem Sie gegenüberstehen, speichern Sie normalerweise zuerst ein Fortschrittsarchiv. Wenn die Herausforderung fehlschlägt, können Sie das Archiv direkt lesen, um den Zustand wiederherzustellen, bevor Sie den BOSS herausfordern. Anschließend können Sie eine Weile üben und dann zurückkommen, um den großen BOSS zu lösen. Für alle Fälle ist es jedoch immer eine gute Idee, eine Datei zu speichern, bevor Sie den BOSS herausfordern. Ein weiteres Beispiel sind Git oder Svn, die Codeverwaltungstools, die wir Programmierer täglich verwenden. Jede Übermittlung ist wie eine Archivsicherung. Wenn es ein Problem mit dem neuen Code gibt, führen Sie einfach einen Rollback durch und führen Sie eine Wiederherstellung durch. Dies sind alles typische Anwendungen des Memomodus. Schauen wir uns diesen Modus gemeinsam an.

Gof-Klassendiagramm und Erklärung

GoF-Definition: Erfassen Sie den internen Zustand eines Objekts und speichern Sie diesen Zustand außerhalb des Objekts, ohne die Kapselung zu zerstören. Auf diese Weise kann das Objekt in Zukunft in seinen ursprünglichen gespeicherten Zustand zurückversetzt werden. Es verfügt über einen internen Zustand, der sich unter verschiedenen Umständen ändern kann. Wenn ein Ereignis eintritt, muss dieser Zustand in seinen ursprünglichen Zustand zurückversetzt werden. Hier haben wir ein CreateMemento() zum Erstellen eines Memos (Archiv) und ein SetMeneto() zum Wiederherstellen des Status (Lesen der Datei).

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;
    }
}
Memo, sehr einfach, wird zum Aufzeichnen des Status verwendet. Durch das Speichern dieses Zustands in Form eines Objekts kann der Urheber problemlos viele Archive erstellen, um verschiedene Zustände aufzuzeichnen.

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

Die verantwortliche Person, auch Managerklasse genannt, speichert das Memo und holt es bei Bedarf von hier aus heraus. Es ist nur für das Speichern verantwortlich und kann das Memo nicht ändern. In komplexen Anwendungen kann dies in eine Liste umgewandelt werden, genau wie in einem Spiel, das selektiv mehrere Archivdatensätze anzeigen kann, aus denen Spieler auswählen können.

class Caretaker
{
    private $memento;
    public function SetMemento($memento)
    {
        $this->memento = $memento;
    }
    public function GetMemento()
    {
        return $this->memento;
    }
}
Im Client-Aufruf hat unser Urheber den Status initialisiert und gespeichert und dann den Status künstlich geändert. Zu diesem Zeitpunkt müssen Sie den Status lediglich über die verantwortliche Person wiederherstellen.

Lassen Sie uns über den Memo-Modus in PHP sprechenUm es ganz klar auszudrücken: Der Memo-Modus besteht darin, eine externe Klasse B den internen Zustand von A speichern zu lassen und diesen Zustand dann zu gegebener Zeit einfach wiederherzustellen.

Es gibt tatsächlich viele Anwendungsszenarien für den Memo-Modus, wie z. B. Browser-Rollback, Datenbanksicherung und -wiederherstellung, Betriebssystemsicherung und -wiederherstellung, Rückgängigmachen und Wiederherstellen von Dokumenten, Bedauern bei Schach- und Kartenspielen usw. Dieser Modus kann das Original beibehalten Server-Kapselung, das heißt, diese Zustände müssen vor externen Objekten verborgen werden, sodass sie nur zur Aufzeichnung an ein Memo-Objekt übergeben werden können

Das Kopieren von Zuständen zwischen dem Urheber und dem Memo kann zu Leistungsproblemen führen, insbesondere aufgrund der Komplexität Große Objekte Der interne Zustand des Computers führt auch zu einigen Codierungslücken, z. B. zum Fehlen bestimmter Zustände. Haben Sie von der Zeitmaschinenfunktion des Mac gehört, die den Computer zu einem bestimmten Zeitpunkt in einen Zustand zurückversetzen kann? Tatsächlich hat auch Windows Ghost eine ähnliche Funktion. Auch unser mobiles Betriebssystem hat beschlossen, eine solche Funktion zu entwickeln. Wenn wir auf Time Machine Backup klicken, werden alle Informationen, Daten und Statusinformationen auf dem Telefon komprimiert und gespeichert. Wenn der Benutzer dies zulässt, laden wir das komprimierte Paket auf unseren Cloud-Server hoch, um zu vermeiden, dass der Telefonspeicher des Benutzers belegt wird , es wird Es kann nur im Mobiltelefonspeicher des Benutzers gespeichert werden. Wenn das Mobiltelefon des Benutzers zu einem bestimmten Zeitpunkt wiederhergestellt werden muss, werden alle Time-Machine-Backups aufgelistet. Der Benutzer kann den Systemstatus des Mobiltelefons mit nur einem Fingerklick wiederherstellen Das ist doch sehr praktisch! !

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

    Beispiel
  • Dieses Mal bin ich wieder beim SMS-Versand Hier ist ein Beispiel. Wenn wir SMS- oder E-Mail-Versandfunktionen ausführen, gibt es normalerweise eine Warteschlange, die den zu sendenden Inhalt aus der Datenbank oder dem Cache liest und ihn sendet. Wenn dies fehlschlägt, wird der Status der SMS ignoriert in „fehlgeschlagen“ oder „erneut gesendet“ geändert werden. Hier ändern wir es direkt wieder in den zuvor nicht gesendeten Zustand und warten dann darauf, dass die nächste Sendewarteschlange erneut sendet.
  • SMS-Versandklassendiagramm

Vollständiger Quellcode: https://github.com/zhangyue0503/designpatterns-php/blob/master/17.memento/source/memento-message.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视频教程

Das obige ist der detaillierte Inhalt vonLassen Sie uns über den Memo-Modus in PHP sprechen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen