概念理解:原型模式是先建立好一個原型對象,而後經過clone原型對象來建立新的對象。適用於大對象的建立,由於建立一個大對象須要很大的開銷,若是每次new就會消耗很大,原型模式僅需內存拷貝便可。php
主要角色:html
Prototype(抽象原型角色):聲明一個克隆自身的接口設計模式
Concrete Prototype(具體原型角色):實現一個克隆自身的操做this
下面咱們觀察源碼:spa
\Libs\Prototype.php.net
<?php namespace Libs; interface Prototype { public function shallowCopy(); public function deepCopy(); }
\Libs\ConcretePrototype.phpprototype
<?php namespace Libs; 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 shallowCopy() { return clone $this; } /** * 深拷貝 * */ public function deepCopy() { $serialize_obj = serialize($this); $clone_obj = unserialize($serialize_obj); return $clone_obj; } }
\Libs\UsePrototype.php設計
<?php namespace Libs; class Demo { public $string; } class UsePrototype { public function shallow() { $demo = new Demo(); $demo->string = "susan"; $object_shallow_first = new ConcretePrototype($demo); $object_shallow_second = $object_shallow_first->shallowCopy(); var_dump($object_shallow_first->getName()); echo '<br/>'; var_dump($object_shallow_second->getName()); echo '<br/>'; $demo->string = "sacha"; var_dump($object_shallow_first->getName()); echo '<br/>'; var_dump($object_shallow_second->getName()); echo '<br/>'; } public function deep() { $demo = new Demo(); $demo->string = "Siri"; $object_deep_first = new ConcretePrototype($demo); $object_deep_second = $object_deep_first->deepCopy(); var_dump($object_deep_first->getName()); echo '<br/>'; var_dump($object_deep_second->getName()); echo '<br/>'; $demo->string = "Demo"; var_dump($object_deep_first->getName()); echo '<br/>'; var_dump($object_deep_second->getName()); echo '<br/>'; } }
調用:code
$up = new \Libs\UsePrototype; $up->shallow(); echo '<hr>'; $up->deep();
結果:htm
object(Libs\Demo)#2 (1) { ["string"]=> string(5) "susan" } object(Libs\Demo)#2 (1) { ["string"]=> string(5) "susan" } object(Libs\Demo)#2 (1) { ["string"]=> string(5) "sacha" } object(Libs\Demo)#2 (1) { ["string"]=> string(5) "sacha" } object(Libs\Demo)#4 (1) { ["string"]=> string(4) "Siri" } object(Libs\Demo)#5 (1) { ["string"]=> string(4) "Siri" } object(Libs\Demo)#4 (1) { ["string"]=> string(4) "Demo" } object(Libs\Demo)#5 (1) { ["string"]=> string(4) "Siri" }
代碼中提到了深拷貝和淺拷貝,那麼咱們先來分析一下這二者的區別
淺拷貝:被拷貝對象的全部變量都含有與原對象相同的值,並且對其餘對象的引用仍然是指向原來的對象,即淺拷貝只負責當前對象實例,對引用的對象不作拷貝。
深拷貝:被拷貝對象的全部的變量都含有與原來對象相同的值,除了那些引用其餘對象的變量,那些引用其餘對象的變量將指向一個被拷貝的新對象,而再也不是原來那些被引用的對象。即深拷貝把要拷貝的對象所引用的對象也拷貝了一次。而這種對被引用到的對象拷貝叫作間接拷貝。
在決定以深拷貝的方式拷貝一個對象的時候,必須決定對間接拷貝的對象時採起淺拷貝仍是深拷貝仍是繼續採用深拷貝。
序列化深拷貝:利用序列化來作深拷貝,把對象寫到流裏的過程是序列化的過程,這一過程稱爲「冷凍」或「醃鹹菜」,反序列化對象的過程叫作「解凍」或「回鮮」。
引用與推薦: