1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
<?php //原型模式:当需要创建的类消耗比较大时可以使用,感觉直接用显示clone也是可以的 class Prototype { private $name = ''; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function copy() { return clone $this; //浅拷贝 } public function __clone() { //被拷贝时,可以定制一些改变 $this->name = $this->name . '(备份)'; } } $test1 = new Prototype(); $test1->setName('张三'); $test2 = $test1->copy(); echo $test1->getName(); echo '<br>'; echo $test2->getName(); //test1输出张三 test2输出张三(备份) 感觉是不是跟$test2 = clone $test1;一样的。。。 //当然被clone的对象里面还有引用的话,浅拷贝是无法完全clone的,需要再次使用clone,如果被clone的对象里面还有引用的话需要层层往上clone。。此时,就不太适合使用原型模式了,可以使用直接序列化和反序列化 //浅复制 class Obj1 { private $name = '我是你的对象'; public function getName() { return $this->name; } } class Obj2 { private $obj = null; public function __construct($obj) { $this->obj = $obj; } public function getObj() { return $this->obj; } } $obj1 = new Obj1(); $obj2 = new Obj2($obj1); $obj3 = clone $obj2; //输出结果为true,说明$obj对象是一个引用,并没有完全clone var_dump(spl_object_hash($obj2->getObj()) === spl_object_hash($obj3->getObj())); //深复制 class Obj4 { private $obj = null; public function __construct($obj) { $this->obj = $obj; } public function getObj() { return $this->obj; } public function __clone() { $this->obj = clone $this->obj; //当对象被clone的时候,再次clone内部对象 } } $obj4 = new Obj4($obj1); $obj5 = clone $obj4; //输出结果为false,因为$obj对象被再次clone了 var_dump(spl_object_hash($obj4->getObj()) === spl_object_hash($obj5->getObj())); //序列化 $obj6 = unserialize(serialize($obj2)); //输出结果为false var_dump(spl_object_hash($obj2->getObj()) === spl_object_hash($obj6->getObj())); |