ホームページ  >  記事  >  バックエンド開発  >  PHPの状態パターンとは何ですか?例を通して学びましょう

PHPの状態パターンとは何ですか?例を通して学びましょう

青灯夜游
青灯夜游転載
2021-07-27 18:33:362073ブラウズ

前の記事「PHP のシングルトン モードについて話しましょう」では、PHP のシングルトン モードについて紹介しました。次の記事では、PHP デザイン パターンのステート モードについて説明します。

PHPの状態パターンとは何ですか?例を通して学びましょう

状態パターンを文字通りに理解するのはそれほど簡単ではありません。ここでのステ​​ータスは何を意味するのでしょうか?ステータスを保存しますか?それはメモモードではありません。実際、ここでの状態はクラスの状態であり、クラスの特定の状態を変更すると、そのクラスは別のクラスのように感じられます。少し難しいので、まず概念を学んでから読みましょう。

Gof クラス図と説明

GoF 定義: 内部状態が変化したときにオブジェクトの動作を変更できるようにします。オブジェクトはそのクラスを変更したようです

GoF クラス図

PHPの状態パターンとは何ですか?例を通して学びましょう

コードの実装

class Context
{
    private $state;
    public function SetState(State $state): void
    {
        $this->state = $state;
    }
    public function Request(): void
    {
        $this->state = $this->state->Handle();
    }
}

コンテキスト クラスは、内部に状態オブジェクトを持つターゲット クラスとみなすこともできます。 Request()を呼び出す場合は、ステータスクラスのHandle()メソッドを呼び出します。その目的は、現在のコンテキスト クラスの状態の変更が外部状態クラスによって制御されることです。

interface State
{
    public function Handle(): State;
}

class ConcreteStateA implements State
{
    public function Handle(): State
    {
        echo '当前是A状态', PHP_EOL;
        return new ConcreteStateB();
    }
}

class ConcreteStateB implements State
{
    public function Handle(): State
    {
        echo '当前是B状态', PHP_EOL;
        return new ConcreteStateA();
    }
}

抽象状態インターフェイスと 2 つの具体的な実装。これら 2 つの特定の実装は、実際には相互に呼び出しています。この実装の効果は、コンテキスト クラスが Request() メソッドを呼び出すたびに、内部状態クラスが別の状態に変化することです。オンとオフを行き来するスイッチのようなものです。

$c = new Context();
$stateA = new ConcreteStateA();
$c->SetState($stateA);
$c->Request();
$c->Request();
$c->Request();
$c->Request();

クライアントの実装は、コンテキスト オブジェクトをインスタンス化して初期状態を設定し、その後、継続的に Request() オブジェクトを呼び出してスイッチ状態の切り替えを実現します。

    道が見えますか?ここでは、状態の変更は外部実装クラスにカプセル化されています。状態はコンテキストまたはターゲット クラス内で切り替わりません。
  • それでは、状態モードの意味は何でしょうか?このデフォルトのクラス図の例は単純すぎます。実際、状態パターンの本当の目的は、複雑な if ネスト問題を解決することです。複雑な if ネスト条件は、判断のために外部状態クラスに 1 つずつ入れられます。次の例では、
  • が次の場合に適用されることがわかります: オブジェクトの動作はその状態に依存し、実行時の状態に応じて動作を変更する必要があります。操作には多数のマルチブランチ条件が含まれます。ステートメント、およびこれらの分岐はオブジェクトの状態に依存します;
  • 状態パターンの特徴は次のとおりです: 特定の状態に関連する動作を局所化する; 状態遷移を明示的にする; 状態オブジェクトを共有できる;
  • オーダーシステム、メンバーシップシステム、OAシステムによく見られる、つまりプロセスの中で様々なステータス変化があり、そのステータスパターンを全体の設計やアーキテクチャに利用できる

弊社では独自のショッピングモールシステムを携帯電話システムにカスタマイズしており、携帯電話から簡単にご注文・ご購入いただけます。注文 (Context) には、未払い、支払い済み、注文完了、注文返金など、複数の状態 (State) が含まれます。これらの状態を対応する状態クラスに配置して実装します。異なる状態クラスが状態の次のアクションを呼び出します。たとえば、支払い後は商品の受け取りを待ち、返金後は購入者が記入するのを待ちます。待って、このようにして、ステートモードをモール内で柔軟に使用できるようになります。 !

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

##例

通常、ショッピング モール アプリケーションには会員システムがあり、通常、レベルが高くなるほど、会員はより多くの割引を享受できます。このとき、ステータス モードを使用すると、会員レベルの割引が簡単に受けられるのでとても便利です。もちろん、最も重要なことは、ステータス モードを使用すると、メンバーシップ レベルを追加または削除する必要がある場合にのみ、対応するメンバー割引ステータス サブクラスを追加できるということです。他のビジネス コードを変更する必要はありません。具体的な実装を見てみましょう。

メンバー割引の画像

PHPの状態パターンとは何ですか?例を通して学びましょう完全なソース コード: https://github.com/zhangyue0503/designpatterns-php / blob/master/22.state/source/state-member.php

<?php

class Member
{
    private $state;
    private $score;

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

    public function SetScore($score)
    {
        $this->score = $score;
    }

    public function GetScore()
    {
        return $this->score;
    }

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

interface State
{
    public function discount($member);
}

class PlatinumMemeberState implements State
{
    public function discount($member)
    {
        if ($member->GetScore() >= 1000) {
            return 0.80;
        } else {
            $member->SetState(new GoldMemberState());
            return $member->discount();
        }
    }
}

class GoldMemberState implements State
{
    public function discount($member)
    {
        if ($member->GetScore() >= 800) {
            return 0.85;
        } else {
            $member->SetState(new SilverMemberState());
            return $member->discount();
        }
    }
}

class SilverMemberState implements State
{
    public function discount($member)
    {
        if ($member->GetScore() >= 500) {
            return 0.90;
        } else {
            $member->SetState(new GeneralMemberState());
            return $member->discount();
        }
    }
}

class GeneralMemberState implements State
{
    public function discount($member)
    {
        return 0.95;
    }
}

$m = new Member();
$m->SetState(new PlatinumMemeberState());

$m->SetScore(1200);
echo &#39;当前会员&#39; . $m->GetScore() . &#39;积分,折扣为:&#39; . $m->discount(), PHP_EOL;

$m->SetScore(990);
echo &#39;当前会员&#39; . $m->GetScore() . &#39;积分,折扣为:&#39; . $m->discount(), PHP_EOL;

$m->SetScore(660);
echo &#39;当前会员&#39; . $m->GetScore() . &#39;积分,折扣为:&#39; . $m->discount(), PHP_EOL;

$m->SetScore(10);
echo &#39;当前会员&#39; . $m->GetScore() . &#39;积分,折扣为:&#39; . $m->discount(), PHP_EOL;

Description

状態モードを使用しない場合Member のdiscount()メソッドでは、if...else...の判定条件を何層も記述する必要がある場合があります

    同時に、メソッドのエクスペリエンスが低下するという問題も発生します。
  • この問題を解決するために、state モードが存在します。
  • discount() 動作の結果がステータスに依存する場合Member オブジェクト自体 (メンバーシップ ポイント) の場合、状態モードが最良の選択です。つまり、上記のオブジェクトの動作はその状態に依存します
  • 元のアドレス: https:/ /juejin.cn/post/6844903991562731534
著者: ハードコア プロジェクト マネージャー

推奨学習: 「PHP ビデオ チュートリアル

以上がPHPの状態パターンとは何ですか?例を通して学びましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。