设计模式之原型模式(php实现)
github地址:https://github.com/ZQCard/design_pattern
1.先了解什么是浅拷贝与深拷贝
//深拷贝:赋值时值完全复制,完全的copy,对其中一个作出改变,不会影响另一个 // //浅拷贝:赋值时,引用赋值,相当于取了一个别名。对其中一个修改,会影响另一个 对象作为参数传递时,也是引用传递
//php 对象复制,是复制对象的引用地址,因此使用 $objA = $objB 这种写法时,$objA与$objB会指向相同的内存地址。当$objA 发生变化时,$objB也会受到影响。
//如果我们要$objA对象复制为$objB对象,复制之后,$objA有什么变化,都不会影响$objB。即$objA与$objB是两个独立的对象,但$objB的初始值是由$objA创建的,比较高效的做法是使用clone()方法。
//$objB = clone $objA;
//$objB的值是在$objA基础加$objA事例对象里clone()方法改变后的实例。
//当对象被复制后,所有的属性中的引用保持不变,指向原来的变量 ******
class Demo
{
public $string;
}
//$a = new Demo();
//$a->string = 1;
//$b = clone $a; // 在堆复制一个一摸一样的 其实是两个对象 但是同时指向的$string的地址是不变的
//var_dump($a); // true
//var_dump($b); // false
//var_dump($b == $a); // true
//var_dump($b === $a); // false
(1)Prototype.class.php(规范子类接口)
<?php namespace Prototype; interface Prototype { public function copy(); public function deepCopy(); }
(2)ConcretePrototype.class.php (具体原型)
<?php
namespace Prototype;
class ConcretePrototype implements Prototype{
private $_obj;
public function __construct($obj)
{
$this->_obj = $obj;
}
public function getObj()
{
return $this->_obj;
}
public function setObj($obj)
{
$this->_obj = $obj;
}
public function copy()
{
return clone $this;
}
public function deepCopy()
{
$object = serialize($this);
$cloneObject = unserialize($object);
return clone $cloneObject;
}
}
(3)prototype.php(客户端)
<?php spl_autoload_register(function ($classObj){ $classObj = str_replace('\\','/',$classObj); include $classObj.".class.php"; }); class Demo { public $string; } //深拷贝:赋值时值完全复制,完全的copy,对其中一个作出改变,不会影响另一个 // //浅拷贝:赋值时,引用赋值,相当于取了一个别名。对其中一个修改,会影响另一个 对象作为参数传递时,也是引用传递 //php 对象复制,是复制对象的引用地址,因此使用 $objA = $objB 这种写法时,$objA与$objB会指向相同的内存地址。当$objA 发生变化时,$objB也会受到影响。 //如果我们要$objA对象复制为$objB对象,复制之后,$objA有什么变化,都不会影响$objB。即$objA与$objB是两个独立的对象,但$objB的初始值是由$objA创建的,比较高效的做法是使用clone()方法。 //$objB = clone $objA; //$objB的值是在$objA基础加$objA事例对象里clone()方法改变后的实例。 //当对象被复制后,所有的属性中的引用保持不变,指向原来的变量 //$a = new Demo(); //$a->string = 1; //$b = clone $a; // 在堆复制一个一摸一样的 其实是两个对象 但是同时指向的$string的地址是不变的 //var_dump($a); // true //var_dump($b); // false //var_dump($b == $a); // true //var_dump($b === $a); // false use Prototype\ConcretePrototype; // 浅拷贝 $demo = new Demo(); $demo->string = 'card'; $object_first = new ConcretePrototype($demo); $object_second = $object_first->copy(); echo '<pre/>'; var_dump($object_first->getObj() == $object_second->getObj()); // true var_dump($object_first->getObj() === $object_second->getObj());// true // 深拷贝 $demo = new Demo(); $demo->string = 'card'; $object_first = new ConcretePrototype($demo); $object_second = $object_first->deepCopy(); echo '<pre/>'; var_dump($object_first); var_dump($object_second); var_dump($object_first->getObj() == $object_second->getObj()); // true var_dump($object_first->getObj() === $object_second->getObj());// false