站長資訊網
        最全最豐富的資訊網站

        一文了解PHP中的原型模式

        在之前的文章《淺談PHP中的迭代器模式》中我們介紹了PHP中的迭代器模式,下面本篇文章帶大家了解一下PHP中的原型模式。

        一文了解PHP中的原型模式

        原型模式其實更形象的來說應該叫克隆模式。它主要的行為是對對象進行克隆,但是又把被克隆的對象稱之為最初的原型,于是,這個模式就這樣被命名了。說真的,從使用方式來看真的感覺叫克隆模式更貼切一些。

        Gof類圖及解釋

        GoF定義:用原型實例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象

        GoF類圖:

        一文了解PHP中的原型模式

        代碼實現:

        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();

        客戶端使用clone來復制一文了解PHP中的原型模式p2也具有相同的$v屬性。

        • 原型模式看似就是復制了一個相同的對象,但是請注意,復制的時候,__construct()方法并沒有被調用,也就是當你運行這段代碼的時候,create只輸出了一次。這也就帶出了原型模式最大的一個特點——減少創(chuàng)建對象時的開銷
        • 基于上述特點,我們可以快速的復制大量相同的對象,比如要給一個數組中塞入大量相同的對象時。
        • 復制出來的對象中如果都是值類型的屬性,我們可以任意修改,不會對原型產生影響。而如果有引用類型的變量,則需要在__clone()方法進行一些處理,否則修改了復制對象的引用變量中的內容,會對原型對象中的內容有影響。

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

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

        實例

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

        原型模式生產手機類圖:

        一文了解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 "中國移動" . $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 = '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();

        說明:

        • 打印了很多東西呀,不過主要的還是看看移動手機,也就是CMPhone中的__clone()方法,我們沒有重新去初始化一個新對象。這時,復制的一文了解PHP中的原型模式cmPhone中的是同一個對象。沒錯,這就是引用的復制問題。引用只是復制了引用的地址,他們指向的是同一個對象。當

          一文了解PHP中的原型模式cmPhone里面的service_province對象里面的屬性也跟著改變了。

        • 在CUPhone中,我們重新new了一個新的service_province對象。這次外面的

          一文了解PHP中的原型模式cuPhone中引用對象的值。

        • 原型模式中最主要的就是要注意上述兩點,而普通的值屬性會直接進行復制,不會產生這個問題。這里又牽涉出另外兩個概念:淺復制深復制
        • 淺復制,是指被復制對象的所有變量都含有與原來對象相同的值,而所有的對其他對象的引用都仍然指向原來的對象
        • 深復制把引用對象的變量指向復制過的新對象,而不是原有的被引用的對象
        • 關于引用和值的問題,我們將在其他的文章中進行講解,請關注微信或掘金號

        原文地址:https://juejin.cn/post/6844903942220939272

        作者:硬核項目經理

        推薦學習:《PHP視頻教程》

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 91精品国产综合久久香蕉| 久久久精品波多野结衣| 国产精品伊人久久伊人电影| 久久夜色精品国产噜噜麻豆| 欧美成人精品一区二三区在线观看| 国产精品亚洲专区在线观看| 亚洲精品无码不卡在线播放HE | 亚洲精品无码久久久久sm| 精品国产婷婷久久久| 一区二区三区精品| 国产精品国产精品国产专区不卡| 色久综合网精品一区二区| 亚洲综合国产精品第一页 | 无码精品一区二区三区在线| 欧美黑人巨大videos精品| 精品a在线观看| 97精品国产自在现线免费观看 | 亚洲国产精品无码久久久不卡| 日韩精品一区二区三区中文字幕| 国内精品99亚洲免费高清| 国产成人精品综合久久久| 亚洲精品人成在线观看| 色偷偷888欧美精品久久久| 欧美精品福利视频| 精品视频一区二区三区在线观看| 99国产欧美久久久精品蜜芽| 久热这里只有精品视频6| 少妇人妻偷人精品免费视频| 亚洲精品二区国产综合野狼| 在线涩涩免费观看国产精品| 亚洲精品一品区二品区三品区| 中文字幕在线精品视频入口一区| 欧美午夜精品久久久久久浪潮| 欧美激情精品久久久久久| 蜜桃麻豆www久久国产精品| 久久无码人妻精品一区二区三区| 欧美日韩精品一区二区三区不卡 | 国产综合精品久久亚洲 | 亚洲精品综合久久| 无码精品人妻一区二区三区人妻斩| 亚洲AV永久纯肉无码精品动漫|