這篇文章將為大家詳細(xì)講解有關(guān)PHP中原型模式的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
創(chuàng)新互聯(lián)專注于通許企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,成都商城網(wǎng)站開發(fā)。通許網(wǎng)站建設(shè)公司,為通許等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站設(shè)計,專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)
原型模式其實更形象的來說應(yīng)該叫克隆模式。它主要的行為是對對象進(jìn)行克隆,但是又把被克隆的對象稱之為最初的原型,于是,這個模式就這樣被命名了。說真的,從使用方式來看真的感覺叫克隆模式更貼切一些。
GoF定義:用原型實例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象
GoF類圖:
代碼實現(xiàn):
abstract class Prototype { public $v = 'clone' . PHP_EOL; public function __construct() { echo 'create' . PHP_EOL; } abstract public function __clone(); }
首先我們通過模擬的方式定義了一個原型,這里主要是模擬了__clone()這個方法。其實這是PHP自帶的一個魔術(shù)方法,根本是不需要我們?nèi)ミM(jìn)行定義的,只需要在原型類中進(jìn)行實現(xiàn)就可以了。當(dāng)外部使用clone關(guān)鍵字進(jìn)行對象克隆時,直接就會進(jìn)入這個魔術(shù)方法中。在這個魔術(shù)方法里面我們可以對屬性進(jìn)行處理,特別是針對引用屬性進(jìn)行一些獨(dú)特的處理。在這個例子中,我們只使用了一個值類型的變量。無法體現(xiàn)出引用類型的問題,我們將在后面的實例中演示對引用類型變量的處理。
class ConcretePrototype1 extends Prototype { public function __clone() { } } class ConcretePrototype2 extends Prototype { public function __clone() { } }
模擬的具體實現(xiàn)的原型,其實就是主要去具體的實現(xiàn)__clone()方法。后面我們看具體的例子時再說明。
class Client { public function operation() { $p1 = new ConcretePrototype1(); $p2 = clone $p1; echo $p1->v; echo $p2->v; } } $c = new Client(); $c->operation();
客戶端使用clone來復(fù)制p2也具有相同的$v屬性。
原型模式看似就是復(fù)制了一個相同的對象,但是請注意,復(fù)制的時候,__construct()方法并沒有被調(diào)用,也就是當(dāng)你運(yùn)行這段代碼的時候,create只輸出了一次。這也就帶出了原型模式最大的一個特點(diǎn)——減少創(chuàng)建對象時的開銷。
基于上述特點(diǎn),我們可以快速的復(fù)制大量相同的對象,比如要給一個數(shù)組中塞入大量相同的對象時。
復(fù)制出來的對象中如果都是值類型的屬性,我們可以任意修改,不會對原型產(chǎn)生影響。而如果有引用類型的變量,則需要在__clone()方法進(jìn)行一些處理,否則修改了復(fù)制對象的引用變量中的內(nèi)容,會對原型對象中的內(nèi)容有影響。
我們的手機(jī)操作系統(tǒng)(也可以想象一下PC電腦的操作系統(tǒng)),都是怎樣安裝到設(shè)備中呢?其實都是不停的復(fù)制拷貝最初的那一套系統(tǒng)。用微軟的例子非常好說明這個問題,當(dāng)年微軟能夠成為一個帝國,其實也是因為他不停的將winodws操作系統(tǒng)拷貝復(fù)制到光盤中,然后賣給千家萬戶(當(dāng)然,這里沒中國什么事兒)。而中國市場呢,大量的高手破解了windows之后也是由這一份文件不停的復(fù)制拷貝才裝到了我們的電腦中。手機(jī)、智能設(shè)備等各類產(chǎn)品的操作系統(tǒng)、軟件都是如此。一次開發(fā)無限拷貝正是軟件行業(yè)暴利的原因。畢竟我們的系統(tǒng)也是由不少的工程師日以繼夜的996在Android原生系統(tǒng)的基礎(chǔ)上開發(fā)出來的,趕緊不斷的復(fù)制到即將出廠的手機(jī)上吧?。?/em>
完整代碼:https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fzhangyue0503%2Fdesignpatterns-php%2Fblob%2Fmaster%2F08.prototype%2Fsource%2Fprototype.php
同樣還是拿手機(jī)來說事兒,這次我們是根據(jù)不同的運(yùn)營商需要去開發(fā)一批定制機(jī),也就是套餐機(jī)。這批手機(jī)說實話都并沒有什么不同,大部分都是相同的配置,但是運(yùn)營商系統(tǒng)不同,而且偶爾有一些型號的CPU和內(nèi)存也可能存在不同。這個時候,我們就可以用原型模式來進(jìn)行快速的復(fù)制并且只修改一部分不相同的地方啦。
原型模式生產(chǎn)手機(jī)類圖:
完整源碼: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 "中國聯(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();
說明:
打印了很多東西呀,不過主要的還是看看移動手機(jī),也就是CMPhone中的__clone()方法,我們沒有重新去初始化一個新對象。這時,復(fù)制的cmPhone中的是同一個對象。沒錯,這就是引用的復(fù)制問題。引用只是復(fù)制了引用的地址,他們指向的是同一個對象。當(dāng)
cmPhone里面的service_province對象里面的屬性也跟著改變了。
在CUPhone中,我們重新new了一個新的service_province對象。這次外面的
cuPhone中引用對象的值。
原型模式中最主要的就是要注意上述兩點(diǎn),而普通的值屬性會直接進(jìn)行復(fù)制,不會產(chǎn)生這個問題。這里又牽涉出另外兩個概念:淺復(fù)制和深復(fù)制
淺復(fù)制,是指被復(fù)制對象的所有變量都含有與原來對象相同的值,而所有的對其他對象的引用都仍然指向原來的對象
深復(fù)制把引用對象的變量指向復(fù)制過的新對象,而不是原有的被引用的對象
關(guān)于引用和值的問題,我們將在其他的文章中進(jìn)行講解,請關(guān)注微信或掘金號
關(guān)于“PHP中原型模式的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
網(wǎng)站名稱:PHP中原型模式的示例分析
文章網(wǎng)址:http://aaarwkj.com/article42/gihhec.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、小程序開發(fā)、品牌網(wǎng)站制作、標(biāo)簽優(yōu)化、自適應(yīng)網(wǎng)站、軟件開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)