ホームページ  >  記事  >  バックエンド開発  >  PHP のフライウェイト パターンについて 1 つの記事で学習します

PHP のフライウェイト パターンについて 1 つの記事で学習します

青灯夜游
青灯夜游転載
2021-07-14 19:32:552873ブラウズ

前回の記事「PHP のプロキシ モードについての話 (フォワード プロキシとリバース プロキシ)」では、PHP のプロキシ モードについて紹介しました。この記事では、デザイン パターンにおける PHP Flyweight パターンについて理解します。 。

PHP のフライウェイト パターンについて 1 つの記事で学習します

フライウェイト モード、「フライウェイト」という言葉は中国語では実際には特別な意味を持たないため、分解して見てみる必要があります。 「翔」は共有、「元」は要素という意味で、ある要素を共有するというとわかりやすいと思います。

#Gof クラス図と説明

GoF 定義: 共有テクノロジを使用して、多数のきめの細かいオブジェクトを効果的にサポートします

GoF クラス図

PHP のフライウェイト パターンについて 1 つの記事で学習します

コードの実装

interface Flyweight
{
    public function operation($extrinsicState) : void;
}

class ConcreteFlyweight implements Flyweight
{
    private $intrinsicState = 101;
    function operation($extrinsicState) : void
    {
        echo '共享享元对象' . ($extrinsicState + $this->intrinsicState) . PHP_EOL;
    }
}

class UnsharedConcreteFlyweight implements Flyweight
{
    private $allState = 1000;
    public function operation($extrinsicState) : void
    {
        echo '非共享享元对象:' . ($extrinsicState + $this->allState) . PHP_EOL;
    }
}

共有の定義インターフェイスとその実装。ここには 2 つの実装があることに注意してください。ConcreteFlyweigh は状態を共有します。UnsharedConcreteFlyweight は共有しないか、その状態を共有する必要はありません。

class FlyweightFactory
{
    private $flyweights = [];

    public function getFlyweight($key) : Flyweight
    {
        if (!array_key_exists($key, $this->flyweights)) {
            $this->flyweights[$key] = new ConcreteFlyweight();
        }
        return $this->flyweights[$key];
    }
}

共有する必要があるオブジェクトを保存し、それをファクトリを使用して必要な共有オブジェクトを作成し、同じキー値の下に一意のオブジェクトのみが存在するようにし、同じオブジェクトを作成するコストを節約します

$factory = new FlyweightFactory();

$extrinsicState = 100;
$flA = $factory->getFlyweight('a');
$flA->operation(--$extrinsicState);

$flB = $factory->getFlyweight('b');
$flB->operation(--$extrinsicState);

$flC = $factory->getFlyweight('c');
$flC->operation(--$extrinsicState);

$flD = new UnsharedConcreteFlyweight();
$flD->operation(--$extrinsicState);

クライアントの呼び出しにより、外部状態 $extrinsicState を共有できるようになります各オブジェクト間

    これは少し興味深いです。このモードのコード量は少なくありません。
  • アプリケーションが非常によく似た多数のオブジェクトを使用し、ほとんどのオブジェクトが' 状態を外部状態に変更できるため、メタ パターンを楽しむのに非常に適しています。
  • ここでのファクトリはオブジェクトのリストを格納します。ファクトリ メソッドや抽象ファクトリのようにオブジェクトを作成するわけではありません。ここで作成すると、オブジェクトが存在すれば直接返され、リストも保持されている
  • フライウェイトモードが実際に使われており、ある程度は使ったことがあるはずです 各種プール技術スレッド プール、接続プールなどの典型的なアプリケーションです。 === にある他の 2 つの同一の文字列 String 型は、PHP または Java で使用できます。これはフライウェイト モードにも当てはまります。それらは同じメモリ アドレスさえ持っています。これは一種の共有ですか?
  • フライウェイト モードに関しては、以下に挙げる例よりもはるかに優れた古典的な例があり、それは碁盤に関するものです。 Go には黒と白の 2 色しかないので、オブジェクトは 2 つあれば十分です。位置ステータスを変更するだけです。興味のある友達は検索してみてください!
  • Laravel の IoC コンテナは、Flyweight パターンの実装とみなすことができます。オブジェクトを配列に保存し、必要に応じてクロージャ メカニズムを通じて取得します。また、一部の状態属性を共有するクラスもいくつかあります。コードを見れば理解できます。

テクノロジーはその殻を変えることに基づいているという事実について話しましょう。結局のところ、誰もが今でも自分の個性を示すためにさまざまな色の携帯電話を好むのです。先ほども言いましたが、色ごとに生産ラインを構築するとなると、莫大な投資が必要ではないでしょうか。幸いなことに、私たちの工場(Xiangyuan Factory)は、各モデルの最も基本的な背景シェル(オブジェクト)のみを生産し、その後、特別な印刷ライン(状態変更)を通じて色付けされます。そうですね、次の Iphone は遅かれ早かれ私たちの真似をするでしょう。まずはあらゆる種類のゴールドとさまざまな豊かな色を集めなければならないようです。もしかしたらドラゴンも召喚できるかもしれません! !

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

##例

予想通り、引き続きテキスト メッセージを送信します。今回はテキスト メッセージは引き続き Alibaba Cloud と Jiguang SMS を使用して送信されますが、今回はフライウェイト モードを使用します。 flyweight ファクトリー ここでは 2 つの異なるタイプのオブジェクトを保存します。内部および外部の状態を通じてオブジェクトを絶えず変化させましょう。

SMS 送信クラス図

PHP のフライウェイト パターンについて 1 つの記事で学習します完全なソース コード: https://github.com/zhangyue0503/designpatterns- php /blob/master/13.flyweights/source/flyweights-message.php

<?php

interface Message
{
    public function send(User $user);
}

class AliYunMessage implements Message
{
    private $template;
    public function __construct($template)
    {
        $this->template = $template;
    }
    public function send(User $user)
    {
        echo &#39;使用阿里云短信向&#39; . $user->GetName() . &#39;发送:&#39;;
        echo $this->template->GetTemplate(), PHP_EOL;
    }
}

class JiGuangMessage implements Message
{
    private $template;
    public function __construct($template)
    {
        $this->template = $template;
    }
    public function send(User $user)
    {
        echo &#39;使用极光短信向&#39; . $user->GetName() . &#39;发送:&#39;;
        echo $this->template->GetTemplate(), PHP_EOL;
    }
}

class MessageFactory
{
    private $messages = [];
    public function GetMessage(Template $template, $type = &#39;ali&#39;)
    {
        $key = md5($template->GetTemplate() . $type);
        if (!key_exists($key, $this->messages)) {
            if ($type == &#39;ali&#39;) {
                $this->messages[$key] = new AliYunMessage($template);
            } else {
                $this->messages[$key] = new JiGuangMessage($template);
            }
        }
        return $this->messages[$key];
    }

    public function GetMessageCount()
    {
        echo count($this->messages);
    }
}

class User
{
    public $name;
    public function GetName()
    {
        return $this->name;
    }
}

class Template
{
    public $template;
    public function GetTemplate()
    {
        return $this->template;
    }
}

// 内部状态
$t1 = new Template();
$t1->template = &#39;模板1,不错哟!&#39;;

$t2 = new Template();
$t2->template = &#39;模板2,还好啦!&#39;;

// 外部状态
$u1 = new User();
$u1->name = &#39;张三&#39;;

$u2 = new User();
$u2->name = &#39;李四&#39;;

$u3 = new User();
$u3->name = &#39;王五&#39;;

$u4 = new User();
$u4->name = &#39;赵六&#39;;

$u5 = new User();
$u5->name = &#39;田七&#39;;

// 享元工厂
$factory = new MessageFactory();

// 阿里云发送
$m1 = $factory->GetMessage($t1);
$m1->send($u1);

$m2 = $factory->GetMessage($t1);
$m2->send($u2);

echo $factory->GetMessageCount(), PHP_EOL; // 1

$m3 = $factory->GetMessage($t2);
$m3->send($u2);

$m4 = $factory->GetMessage($t2);
$m4->send($u3);

echo $factory->GetMessageCount(), PHP_EOL; // 2

$m5 = $factory->GetMessage($t1);
$m5->send($u4);

$m6 = $factory->GetMessage($t2);
$m6->send($u5);

echo $factory->GetMessageCount(), PHP_EOL; // 2

// 加入极光
$m1 = $factory->GetMessage($t1, &#39;jg&#39;);
$m1->send($u1);

$m2 = $factory->GetMessage($t1);
$m2->send($u2);

echo $factory->GetMessageCount(), PHP_EOL; // 3

$m3 = $factory->GetMessage($t2);
$m3->send($u2);

$m4 = $factory->GetMessage($t2, &#39;jg&#39;);
$m4->send($u3);

echo $factory->GetMessageCount(), PHP_EOL; // 4

$m5 = $factory->GetMessage($t1, &#39;jg&#39;);
$m5->send($u4);

$m6 = $factory->GetMessage($t2, &#39;jg&#39;);
$m6->send($u5);

echo $factory->GetMessageCount(), PHP_EOL; // 4

Description

コードは少し長くなります。しかし実際には、4 種類のオブジェクトを生成する 2 種類のクラスがあります。ここでは、各クラスの異なるオブジェクトをテンプレートに基づいて区別しています。

    このように組み合わせた方が便利です。他のモードと組み合わせて、工場を最適化します。まあ、未来は無限です。考えてみてください。
  • フライウェイト モードは、システム内に類似のオブジェクトが多数存在し、バッファ プールが必要なシナリオに適しています。メモリ使用量が削減され、効率が向上しますが、複雑さが増し、内部メモリの共有が必要になります。
  • # 最も重要な機能は、一意の識別子を持っていることです。オブジェクトが既にメモリ内に存在する場合、オブジェクトは作成されずに直接返されます。 #元のアドレス: https://juejin.cn /post/6844903965814259726
  • 著者: ハードコア プロジェクト マネージャー
  • 推奨学習: 「PHP ビデオ チュートリアル

以上がPHP のフライウェイト パターンについて 1 つの記事で学習しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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