8. 实现
<?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() { /** 深拷贝 */ return clone $this; /** 浅拷贝 */ //return $this; } } class Client { /** * Main program. */ public static function main() { $object1 = new ConcretePrototype(11); $object_copy = $object1->copy(); var_dump($object1->getName()); echo '<br />'; var_dump($object_copy->getName()); echo '<br />'; $object1->setName(22); var_dump($object1->getName()); echo '<br />'; var_dump($object_copy->getName()); echo '<br />'; } } Client::main(); ?>
9. 浅拷贝和深拷贝
原型模式的原理图:
浅拷贝
被拷贝对象的所有变量都含有与原对象相同的值,而且对其他对象的引用仍然是指向原来的对象。即浅拷贝只负责当前对象实例,对引用的对象不做拷贝。
浅复制后的对象和对象副本的情况:
深拷贝
被拷贝对象的所有的变量都含有与原来对象相同的值,除了那些引用其他对象的变量。那些引用其他对象的变量将指向一个被拷贝的新对象,而不再是原有那些被引用对象。即 深拷贝把要拷贝的对象所引用的对象也都拷贝了一次,而这种对被引用到的对象拷贝叫做间接拷贝。
深复制的对象和对象副本的情况:
深拷贝要深入到多少层,是一个不确定的问题。
在决定以深拷贝的方式拷贝一个对象的时候,必须决定对间接拷贝的对象是采取浅拷贝还是深拷贝还是继续采用深拷贝。
因此,在采取深拷贝时,需要决定多深才算深。此外,在深拷贝的过程中,很可能会出现循环引用的问题。
10. 带Prototype Manager的原型模式
原型模式的第二种形式是带原型管理器的原型模式,其UML图如下:
原型管理器(Prototype Manager)角色:创建具体原型类的对象,并记录每一个被创建的对象。