PHPのメモモードについて話しましょう

青灯夜游
リリース: 2023-04-10 11:40:02
転載
2191 人が閲覧しました

前回の記事「PHPのビルダーパターンの詳細分析」ではPHPのビルダーパターンについて紹介しましたが、次の記事ではPHPデザインパターンのメモパターンについて理解していきます。

PHPのメモモードについて話しましょう

メモ、この名前は実際にその機能を非常にわかりやすく説明しています。典型的な例は、もともとハードディスクゲームをプレイしたときのアーカイブ機能です。これから直面する大きなボスが心配なときは、通常、最初に進行状況のアーカイブを保存します。挑戦に失敗した場合は、アーカイブを直接読み込んでBOSSに挑戦する前の状態に戻すことができ、しばらく楽しく練習して再び大BOSSを解くことができます。ただし、念のため、BOSS に挑戦する前にファイルを保存しておくことをお勧めします。もう 1 つの例は、プログラマーが毎日使用するコード管理ツールである Git または Svn です。各提出はアーカイブのバックアップのようなもので、新しいコードに問題がある場合は、ロールバックして回復するだけです。これらはメモモードの代表的な応用例ですので、一緒に見ていきましょう。

Gof クラス図と説明

GoF 定義: カプセル化を破壊することなくオブジェクトの内部状態をキャプチャし、この状態をこの外部に保存します。物体。このようにして、オブジェクトを元の保存状態に復元できます

#GoF クラス図:

PHPのメモモードについて話しましょう

##コード実装:

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;
    }
}
ログイン後にコピー
発信者は開始者とも呼ばれます。さまざまな状況下で変化する可能性のある内部状態があります。イベントが発生すると、この状態を元の状態に戻す必要があります。ここでは、メモ (アーカイブ) を作成するための 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();
ログイン後にコピー

クライアント呼び出しで、発信者は状態を初期化して保存し、その後状態を人為的に変更しました。このときは担当者を通じてステータスを復元するだけで済みます。

端的に言えば、メモ モードは、外部クラス B に A の内部状態を保存させ、適切なタイミングでその状態を簡単に復元することです。
    #実際には、ブラウザのロールバック、データベースのバックアップと復元、オペレーティング システムのバックアップと復元、ドキュメントの取り消しとやり直し、チェスやカード ゲームの後悔など、メモ モードには多くの応用シナリオがあります。
  • このモードは、発信元のカプセル化を維持できます。つまり、これらの状態は外部オブジェクトから隠す必要があるため、記録するためにメモ オブジェクトにのみ渡すことができます
  • 状態のコピーの可能性発信者とメモの間でパフォーマンスの問題、特に大きなオブジェクトの複雑で多数の内部状態が発生するほか、一部の状態の欠落などのコーディングの抜け穴も発生します
  • Mac のタイムマシン機能 コンピュータを特定時点の状態に復元できることは誰もが知っています。実はWindowsのゴーストにも同様の機能があります。当社のモバイルオペレーティングシステムもそのような機能を開発することを決定しました。 [Time Machine バックアップ] をクリックすると、携帯電話上のすべての情報、データ、およびステータス情報が圧縮されて保存されます。ユーザーが許可した場合、ユーザーの携帯電話のメモリを占有することを避けるために、圧縮されたパッケージがクラウド サーバーにアップロードされます。それ以外の場合は、圧縮パッケージがクラウド サーバーにアップロードされます。ユーザーの携帯電話のメモリにのみ保存できます。ユーザーの携帯電話を特定の時点に復元する必要がある場合、すべてのタイムマシンのバックアップがリストされ、ユーザーはワンクリックで携帯電話のシステム状態をその時点の状態に復元できます。すごく便利ですね! !

#完全なコード: https://github.com/zhangyue0503/designpatterns-php/blob/master/17.memento/source/memento.php

##例

今回はテキスト メッセージを送信する例に戻ります。通常、テキスト メッセージや電子メールの送信などの機能を実行する場合、送信するコンテンツをデータベースまたはキャッシュから読み取って送信するキューが存在します。成功した場合は無視され、失敗した場合は、メッセージのステータスが表示されます。テキスト メッセージは失敗または再送信に変更されます。ここでは、直接前の未送信状態に戻し、次の送信キューが再度送信を行うのを待ちます。

SMS 送信クラス図

完全なソース コード: 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视频教程

以上がPHPのメモモードについて話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート