PHP中原型模式的示例分析

這篇文章將為大家詳細(xì)講解有關(guān)PHP中原型模式的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)專(zhuān)注于通許企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,成都商城網(wǎng)站開(kāi)發(fā)。通許網(wǎng)站建設(shè)公司,為通許等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站設(shè)計(jì),專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)

原型模式其實(shí)更形象的來(lái)說(shuō)應(yīng)該叫克隆模式。它主要的行為是對(duì)對(duì)象進(jìn)行克隆,但是又把被克隆的對(duì)象稱(chēng)之為最初的原型,于是,這個(gè)模式就這樣被命名了。說(shuō)真的,從使用方式來(lái)看真的感覺(jué)叫克隆模式更貼切一些。

Gof類(lèi)圖及解釋

GoF定義:用原型實(shí)例指定創(chuàng)建對(duì)象的種類(lèi),并且通過(guò)拷貝這些原型創(chuàng)建新的對(duì)象

GoF類(lèi)圖:

PHP中原型模式的示例分析

代碼實(shí)現(xiàn):

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

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

    abstract public function __clone();
}

首先我們通過(guò)模擬的方式定義了一個(gè)原型,這里主要是模擬了__clone()這個(gè)方法。其實(shí)這是PHP自帶的一個(gè)魔術(shù)方法,根本是不需要我們?nèi)ミM(jìn)行定義的,只需要在原型類(lèi)中進(jìn)行實(shí)現(xiàn)就可以了。當(dāng)外部使用clone關(guān)鍵字進(jìn)行對(duì)象克隆時(shí),直接就會(huì)進(jìn)入這個(gè)魔術(shù)方法中。在這個(gè)魔術(shù)方法里面我們可以對(duì)屬性進(jìn)行處理,特別是針對(duì)引用屬性進(jìn)行一些獨(dú)特的處理。在這個(gè)例子中,我們只使用了一個(gè)值類(lèi)型的變量。無(wú)法體現(xiàn)出引用類(lèi)型的問(wèn)題,我們將在后面的實(shí)例中演示對(duì)引用類(lèi)型變量的處理。

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

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

模擬的具體實(shí)現(xiàn)的原型,其實(shí)就是主要去具體的實(shí)現(xiàn)__clone()方法。后面我們看具體的例子時(shí)再說(shuō)明。

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

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

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

客戶端使用clone來(lái)復(fù)制PHP中原型模式的示例分析p2也具有相同的$v屬性。

  • 原型模式看似就是復(fù)制了一個(gè)相同的對(duì)象,但是請(qǐng)注意,復(fù)制的時(shí)候,__construct()方法并沒(méi)有被調(diào)用,也就是當(dāng)你運(yùn)行這段代碼的時(shí)候,create只輸出了一次。這也就帶出了原型模式最大的一個(gè)特點(diǎn)——減少創(chuàng)建對(duì)象時(shí)的開(kāi)銷(xiāo)。

  • 基于上述特點(diǎn),我們可以快速的復(fù)制大量相同的對(duì)象,比如要給一個(gè)數(shù)組中塞入大量相同的對(duì)象時(shí)。

  • 復(fù)制出來(lái)的對(duì)象中如果都是值類(lèi)型的屬性,我們可以任意修改,不會(huì)對(duì)原型產(chǎn)生影響。而如果有引用類(lèi)型的變量,則需要在__clone()方法進(jìn)行一些處理,否則修改了復(fù)制對(duì)象的引用變量中的內(nèi)容,會(huì)對(duì)原型對(duì)象中的內(nèi)容有影響。

我們的手機(jī)操作系統(tǒng)(也可以想象一下PC電腦的操作系統(tǒng)),都是怎樣安裝到設(shè)備中呢?其實(shí)都是不停的復(fù)制拷貝最初的那一套系統(tǒng)。用微軟的例子非常好說(shuō)明這個(gè)問(wèn)題,當(dāng)年微軟能夠成為一個(gè)帝國(guó),其實(shí)也是因?yàn)樗煌5膶inodws操作系統(tǒng)拷貝復(fù)制到光盤(pán)中,然后賣(mài)給千家萬(wàn)戶(當(dāng)然,這里沒(méi)中國(guó)什么事兒)。而中國(guó)市場(chǎng)呢,大量的高手破解了windows之后也是由這一份文件不停的復(fù)制拷貝才裝到了我們的電腦中。手機(jī)、智能設(shè)備等各類(lèi)產(chǎn)品的操作系統(tǒng)、軟件都是如此。一次開(kāi)發(fā)無(wú)限拷貝正是軟件行業(yè)暴利的原因。畢竟我們的系統(tǒng)也是由不少的工程師日以繼夜的996在Android原生系統(tǒng)的基礎(chǔ)上開(kāi)發(fā)出來(lái)的,趕緊不斷的復(fù)制到即將出廠的手機(jī)上吧!!

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

實(shí)例

同樣還是拿手機(jī)來(lái)說(shuō)事兒,這次我們是根據(jù)不同的運(yùn)營(yíng)商需要去開(kāi)發(fā)一批定制機(jī),也就是套餐機(jī)。這批手機(jī)說(shuō)實(shí)話都并沒(méi)有什么不同,大部分都是相同的配置,但是運(yùn)營(yíng)商系統(tǒng)不同,而且偶爾有一些型號(hào)的CPU和內(nèi)存也可能存在不同。這個(gè)時(shí)候,我們就可以用原型模式來(lái)進(jìn)行快速的復(fù)制并且只修改一部分不相同的地方啦。

原型模式生產(chǎn)手機(jī)類(lèi)圖:

PHP中原型模式的示例分析

完整源碼: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 "中國(guó)移動(dòng)" . $this->system;
    }
}
class ChinaUnicom implements ServiceProvicer
{
    public $system;
    public function getSystem(){
        return "中國(guó)聯(lián)通" . $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 = 'TD-CDMA';
$cmPhone1 = clone $cmPhone;
$cmPhone1->service_province->system = 'TD-CDMA1';

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 = 'WCDMA';
$cuPhone1 = clone $cuPhone;
$cuPhone1->rom = "128G";
$cuPhone1->service_province->system = 'WCDMA1';

var_dump($cuPhone);
var_dump($cuPhone1);
echo $cuPhone->service_province->getSystem();
echo $cuPhone1->service_province->getSystem();

說(shuō)明:

  • 打印了很多東西呀,不過(guò)主要的還是看看移動(dòng)手機(jī),也就是CMPhone中的__clone()方法,我們沒(méi)有重新去初始化一個(gè)新對(duì)象。這時(shí),復(fù)制的PHP中原型模式的示例分析cmPhone中的是同一個(gè)對(duì)象。沒(méi)錯(cuò),這就是引用的復(fù)制問(wèn)題。引用只是復(fù)制了引用的地址,他們指向的是同一個(gè)對(duì)象。當(dāng)

    PHP中原型模式的示例分析cmPhone里面的service_province對(duì)象里面的屬性也跟著改變了。

  • 在CUPhone中,我們重新new了一個(gè)新的service_province對(duì)象。這次外面的

    PHP中原型模式的示例分析cuPhone中引用對(duì)象的值。

  • 原型模式中最主要的就是要注意上述兩點(diǎn),而普通的值屬性會(huì)直接進(jìn)行復(fù)制,不會(huì)產(chǎn)生這個(gè)問(wèn)題。這里又牽涉出另外兩個(gè)概念:淺復(fù)制深復(fù)制

  • 淺復(fù)制,是指被復(fù)制對(duì)象的所有變量都含有與原來(lái)對(duì)象相同的值,而所有的對(duì)其他對(duì)象的引用都仍然指向原來(lái)的對(duì)象

  • 深復(fù)制把引用對(duì)象的變量指向復(fù)制過(guò)的新對(duì)象,而不是原有的被引用的對(duì)象

  • 關(guān)于引用和值的問(wèn)題,我們將在其他的文章中進(jìn)行講解,請(qǐng)關(guān)注微信或掘金號(hào)

關(guān)于“PHP中原型模式的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

網(wǎng)站名稱(chēng):PHP中原型模式的示例分析
文章網(wǎng)址:http://bm7419.com/article42/gihhec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、小程序開(kāi)發(fā)品牌網(wǎng)站制作、標(biāo)簽優(yōu)化自適應(yīng)網(wǎng)站、軟件開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開(kāi)發(fā)公司