學(xué)習(xí)php設(shè)計(jì)模式 php實(shí)現(xiàn)原型模式(prototype)
一、意圖
用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象
二、原型模式結(jié)構(gòu)圖
三、原型模式中主要角色
抽象原型(Prototype)角色:聲明一個(gè)克隆自身的接口
具體原型(Concrete Prototype)角色:實(shí)現(xiàn)一個(gè)克隆自身的操作
四、原型模式的優(yōu)點(diǎn)和缺點(diǎn)
Prototype模式優(yōu)點(diǎn):
1、可以在運(yùn)行時(shí)刻增加和刪除產(chǎn)品
2、可以改變值以指定新對(duì)象
3、可以改變結(jié)構(gòu)以指定新對(duì)象
4、減少子類的構(gòu)造
5、用類動(dòng)態(tài)配置應(yīng)用
Prototype模式的缺點(diǎn):
Prototype模式的最主要缺點(diǎn)就是每一個(gè)類必須配備一個(gè)克隆方法。
而且這個(gè)克隆方法需要對(duì)類的功能進(jìn)行通盤考慮,這對(duì)全新的類來說不是很難,但對(duì)已有的類進(jìn)行改造時(shí),不一定是件容易的事。
五、原型模式適用場(chǎng)景
1、當(dāng)一個(gè)系統(tǒng)應(yīng)該獨(dú)立于它的產(chǎn)品創(chuàng)建、構(gòu)成和表示時(shí),要使用Prototype模式
2、當(dāng)要實(shí)例化的類是在運(yùn)行時(shí)刻指定時(shí),例如動(dòng)態(tài)加載
3、為了避免創(chuàng)建一個(gè)與產(chǎn)品類層次平等的工廠類層次時(shí);
4、當(dāng)一個(gè)類的實(shí)例只能有幾個(gè)不同狀態(tài)組合中的一種時(shí)。建立相應(yīng)數(shù)目的原型并克隆它們可能比每次用合適的狀態(tài)手工實(shí)例化該類更方便一些
六、原型模式與其它模式
抽象工廠模式(abstract factory模式):Abstract Factory模式與Prototype模式在某種方面是相互競(jìng)爭的,但是也可以一起使用。
七、原型模式PHP示例
<?php /** * 抽象原型角色 */ interface Prototype { public function copy(); } /** * 具體原型角色 */ class ConcretePrototype implements Prototype{ private $_name; public function __construct($name) { $this->_name = $name; } public function setName($name) { $this->_name = $name; } public function getName() { return $this->_name; } public function copy() { /* 深拷貝實(shí)現(xiàn) $serialize_obj = serialize($this); // 序列化 $clone_obj = unserialize($serialize_obj); // 反序列化 return $clone_obj; */ return clone $this; // 淺拷貝 } } /** * 測(cè)試深拷貝用的引用類 */ class Demo { public $array; } class Client { /** * Main program. */ public static function main() { $demo = new Demo(); $demo->array = array(1, 2); $object1 = new ConcretePrototype($demo); $object2 = $object1->copy(); var_dump($object1->getName()); echo '<br />'; var_dump($object2->getName()); echo '<br />'; $demo->array = array(3, 4); var_dump($object1->getName()); echo '<br />'; var_dump($object2->getName()); echo '<br />'; } } Client::main(); ?>
補(bǔ)充:淺拷貝與深拷貝
淺拷貝
被拷貝對(duì)象的所有變量都含有與原對(duì)象相同的值,而且對(duì)其他對(duì)象的引用仍然是指向原來的對(duì)象。
即 淺拷貝只負(fù)責(zé)當(dāng)前對(duì)象實(shí)例,對(duì)引用的對(duì)象不做拷貝。
深拷貝
被拷貝對(duì)象的所有的變量都含有與原來對(duì)象相同的值,除了那些引用其他對(duì)象的變量。那些引用其他對(duì)象的變量將指向一個(gè)被拷貝的新對(duì)象,而不再是原有那些被引用對(duì)象。
即 深拷貝把要拷貝的對(duì)象所引用的對(duì)象也都拷貝了一次,而這種對(duì)被引用到的對(duì)象拷貝叫做間接拷貝。
深拷貝要深入到多少層,是一個(gè)不確定的問題。
在決定以深拷貝的方式拷貝一個(gè)對(duì)象的時(shí)候,必須決定對(duì)間接拷貝的對(duì)象是采取淺拷貝還是深拷貝還是繼續(xù)采用深拷貝。
因此,在采取深拷貝時(shí),需要決定多深才算深。此外,在深拷貝的過程中,很可能會(huì)出現(xiàn)循環(huán)引用的問題。
利用序列化來做深拷貝
利用序列化來做深拷貝,把對(duì)象寫到流里的過程是序列化(Serilization)過程,但在業(yè)界又將串行化這一過程形象的稱為“冷凍”或“腌咸菜”過程;而把對(duì)象從流中讀出來的過程則叫做反序列化(Deserialization)過程,也稱為“解凍”或“回鮮”過程。
在PHP中使用serialize和unserialize函數(shù)實(shí)現(xiàn)序列化和反序列化。
在上面的代碼中的注釋就是一個(gè)先序列化再反序列化實(shí)現(xiàn)深拷貝的過程。
以上就是使用php實(shí)現(xiàn)原型模式的代碼,還有一些關(guān)于原型模式的概念區(qū)分,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
PHP動(dòng)態(tài)分頁函數(shù),PHP開發(fā)分頁必備啦
PHP動(dòng)態(tài)分頁函數(shù),PHP開發(fā)分頁必備啦。其實(shí)吧,這個(gè)是必用的,不說了,PHP動(dòng)態(tài)分頁函數(shù)還是不錯(cuò),比較簡單吧2011-11-11php圖片處理:加水印、縮略圖的實(shí)現(xiàn)(自定義函數(shù):watermark、thumbnail)
圖片處理:加水印、縮略圖的實(shí)現(xiàn)(自定義函數(shù):watermark、thumbnail)代碼有點(diǎn)長,但不復(fù)雜。2010-12-12PHP基于phpqrcode生成帶LOGO圖像的二維碼實(shí)例
這篇文章主要介紹了PHP基于phpqrcode生成帶LOGO圖像的二維碼,可實(shí)現(xiàn)生成帶logo與不帶logo兩種二維碼的功能,非常簡單實(shí)用,需要的朋友可以參考下2015-07-07php Yii2框架創(chuàng)建定時(shí)任務(wù)方法詳解
Yii2是一個(gè)基于組件、用于開發(fā)大型Web應(yīng)用的高性能PHP框架,采用嚴(yán)格的OOP編寫,并有著完善的庫引用以及全面的教程,該框架提供了Web 2.0應(yīng)用開發(fā)所需要的幾乎一切功能,是最有效率的PHP框架之一2022-09-09php異常:Parse error: syntax error, unexpected T_ENCAPSED_AND_W
PHP會(huì)出現(xiàn)eval()'d code error 錯(cuò)誤提示的原因一般都是因?yàn)槟0邋e(cuò)誤,原因有以下幾種情況2011-05-05PHP 加密 Password Hashing API基礎(chǔ)知識(shí)點(diǎn)
在本篇文章里小編給大家分享的是一篇關(guān)于PHP 加密 Password Hashing API基礎(chǔ)知識(shí)點(diǎn),有興趣的朋友們可以學(xué)習(xí)下。2020-03-03