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

PHP のプロトタイプ パターンについて 1 つの記事で学習します

青灯夜游
青灯夜游転載
2021-07-07 19:22:582963ブラウズ

前回の記事「 PHP のイテレータ パターンについての簡単な説明 」では PHP のイテレータ パターンについて紹介しましたが、この記事では PHP のプロトタイプ パターンについて理解します。

PHP のプロトタイプ パターンについて 1 つの記事で学習します

#プロトタイプ モードは、実際にはクローン モードと呼ばれています。その主な動作はオブジェクトのクローンを作成することですが、クローンされたオブジェクトを元のプロトタイプと呼ぶため、このパターンに名前が付けられています。正直、使い方からするとクローンモードと呼んだ方が適切な気がします。

Gof クラス図と説明

GoF 定義: プロトタイプ インスタンスを使用して、作成するオブジェクトの種類を指定し、次のようにして新しいオブジェクトを作成します。これらのプロトタイプのコピー

GoF クラス図:

PHP のプロトタイプ パターンについて 1 つの記事で学習します

##コードの実装:

abstract class Prototype
{
    public $v = 'clone' . PHP_EOL;

    public function __construct()
    {
        echo 'create' . PHP_EOL;
    }

    abstract public function __clone();
}

まず、シミュレーションを通じてプロトタイプを定義します. ここでは主に __clone() メソッドをシミュレーションします。実は、これは PHP に付属している魔法のメソッドで、定義する必要はまったくなく、プロトタイプ クラスに実装するだけで済みます。 clone キーワードを外部で使用してオブジェクトのクローンを作成する場合は、このマジック メソッドを直接入力することになります。この魔法のメソッドでは、プロパティ、特に参照プロパティに対するいくつかの独自の処理を処理できます。この例では、値型変数のみを使用しました。参照型の問題が反映されないため、参照型変数の処理については後の例で説明します。

class ConcretePrototype1 extends Prototype
{
    public function __clone()
    {
    }
}

class ConcretePrototype2 extends Prototype
{
    public function __clone()
    {
    }
}

シミュレーションの特定の実装のプロトタイプは、実際には __clone() メソッドのメイン実装です。これについては、後で具体的な例を見て説明します。

class Client
{
    public function operation()
    {
        $p1 = new ConcretePrototype1();
        $p2 = clone $p1;

        echo $p1->v;
        echo $p2->v;
    }
}

$c = new Client();
$c->operation();

クライアントはクローンを使用してコピーします

p2 にも同じ $v 属性があります。 PHP のプロトタイプ パターンについて 1 つの記事で学習します

    プロトタイプ モードは同じオブジェクトをコピーしているように見えますが、コピーするときに __construct() メソッドが呼び出されないことに注意してください。つまり、このコードを実行すると、出力は 1 回だけ作成されます。これにより、プロトタイプ パターンの最大の特徴の 1 つである
  • オブジェクト作成のオーバーヘッドを削減する ことも可能になります。
  • 上記の特性に基づいて、多数の同一オブジェクトを配列に詰め込みたい場合などに、多数の同一オブジェクトを迅速にコピーできます。
  • コピーされたオブジェクトがすべて値型属性の場合、プロトタイプに影響を与えることなく任意に変更できます。参照型変数がある場合は、__clone()メソッドで何らかの処理を行う必要があり、そうでない場合、コピーしたオブジェクトの参照変数の内容を変更すると、プロトタイプオブジェクトの内容に影響を与えます。

モバイル オペレーティング システム (PC のオペレーティング システムも想像してください) はデバイスにどのようにインストールされますか?実際、彼らは元のシステムを絶えずコピーしてコピーしています。 Microsoft の例は、この問題を非常によく示しています。Microsoft が当時帝国になれたのは、Winodws オペレーティング システムのコピーを CD にコピーし、それを何千もの家庭に販売し続けたからです (もちろん、ここでは中国に何の問題もありません) )。中国市場に関しては、多数の専門家が Windows をクラックし、このファイルをコンピュータにインストールする前に継続的にコピーしました。これは、携帯電話やスマートデバイスなどのさまざまな製品のオペレーティング システムやソフトウェアにも当てはまります。 1 つの開発の無制限のコピーが、ソフトウェア業界で莫大な利益をもたらす理由です。何しろ当社のシステムはAndroidネイティブシステムをベースに多くのエンジニアが日夜努力して開発したものですから、出荷間近の携帯電話に急いでコピーしてください! !

完整代码:https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fzhangyue0503%2Fdesignpatterns-php%2Fblob%2Fmaster%2F08.prototype%2Fsource%2Fprototype.php

Example

再び携帯電話の話に戻りますが、今回はさまざまな通信事業者のニーズに基づいてカスタマイズされた一連の電話、つまりパッケージ電話を開発しています。正直なところ、これらの携帯電話には違いはなく、ほとんどの携帯電話は同じ構成ですが、キャリアのシステムが異なり、場合によっては CPU やメモリが異なるモデルもあります。現時点では、プロトタイプ モードを使用して、相違点の一部のみをすばやくコピーして変更できます。

プロトタイプ モードの製品携帯電話クラス図:

#

完整源码:https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fzhangyue0503%2Fdesignpatterns-php%2Fblob%2Fmaster%2F08.prototype%2Fsource%2Fprototype-phone.php
<?php
interface ServiceProvicer
{
    public function getSystem();
}

class ChinaMobile implements ServiceProvicer
{
    public $system;
    public function getSystem(){
        return "中国移动" . $this->system;
    }
}
class ChinaUnicom implements ServiceProvicer
{
    public $system;
    public function getSystem(){
        return "中国联通" . $this->system;
    }
}

class Phone 
{
    public $service_province;
    public $cpu;
    public $rom;
}

class CMPhone extends Phone
{
    function __clone()
    {
        // $this->service_province = new ChinaMobile();
    }
}

class CUPhone extends Phone
{
    function __clone()
    {
        $this->service_province = new ChinaUnicom();
    }
}


$cmPhone = new CMPhone();
$cmPhone->cpu = "1.4G";
$cmPhone->rom = "64G";
$cmPhone->service_province = new ChinaMobile();
$cmPhone->service_province->system = &#39;TD-CDMA&#39;;
$cmPhone1 = clone $cmPhone;
$cmPhone1->service_province->system = &#39;TD-CDMA1&#39;;

var_dump($cmPhone);
var_dump($cmPhone1);
echo $cmPhone->service_province->getSystem();
echo $cmPhone1->service_province->getSystem();


$cuPhone = new CUPhone();
$cuPhone->cpu = "1.4G";
$cuPhone->rom = "64G";
$cuPhone->service_province = new ChinaUnicom();
$cuPhone->service_province->system = &#39;WCDMA&#39;;
$cuPhone1 = clone $cuPhone;
$cuPhone1->rom = "128G";
$cuPhone1->service_province->system = &#39;WCDMA1&#39;;

var_dump($cuPhone);
var_dump($cuPhone1);
echo $cuPhone->service_province->getSystem();
echo $cuPhone1->service_province->getSystem();
PHP のプロトタイプ パターンについて 1 つの記事で学習します

説明:

    たくさんのことを出力しましたが、主なことは携帯電話、つまり CMPhone の __clone() メソッドに注目することであり、新しいオブジェクトを再初期化することはしませんでした。この時点で、コピーされた
  • cmPhone には同じオブジェクトが含まれています。はい、これは参照の重複の問題です。参照は参照のアドレスをコピーするだけで、同じオブジェクトを指します。いつ###

    cmPhone の service_province オブジェクトの属性も変更されました。

  • CUPhone で、新しい service_province オブジェクトを作成しました。今回は、

    #cuPhone の外部にある参照オブジェクトの値です。

  • プロトタイプ モードで最も重要なことは、上記 2 点に注意することですが、通常の値属性は直接コピーされるため、この問題は発生しません。ここには他の 2 つの概念が関係しています:
  • 浅いコピー深いコピー
  • 浅いコピーとは、コピーされたオブジェクトのすべての変数に元のオブジェクトと同じ変数が含まれていることを意味します。 、そして他のオブジェクトへのすべての参照は依然として元のオブジェクトを指します
  • #ディープコピーは、参照されるオブジェクトの変数を、元の参照されるオブジェクトではなく、コピーされた新しいオブジェクトを指します
  • 参照の問題についてWeChat または Nuggets アカウントをフォローしてください
  • ##元のアドレス: https://juejin.cn/post/ 6844903942220939272
著者:ハードコア プロジェクト マネージャー

推奨学習: 「

PHP ビデオ チュートリアル

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

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