原型模式
通过创建原型,然后使用克隆方法实现对象创建而不是使用标准的 new 方式
作用:
对一些大型对象,每次去new,初始化开销很大,这个时候我们 先new 一个模版对象,然后其他实例都去clone这个模版, 这样可以节约不少性能。这个模版,就是原型(Prototype)
使用场景:
- 大数据量 (例如:通过 ORM 模型一次性往数据库插入 1,000,000 条数据)
UML图:
对象的浅复制和深复制
浅复制:clone
- 比如
clone new Db();
- 当被克隆对象的属性中有对象等引用的时候,浅复制出来的对象的这个属性会指向同一个引用,即两个对象其中任何一个的这个属性发生变化都会发生变化,也有这样的应用场景
深复制:利用序列化和反序列化实现、或者在class的__clone方法中对引用属性进行一次单独的clone
- 比如:
unserialize(serialize(new Db()));
- 当被克隆对象的属性中有对象等引用的时候,深复制出来的对象的这个属性也是单独复制的,即两个对象完全互不相干
Demo
Github地址:
实现
Company.php
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?php
namespace App\ProtoType;
class Company { private $name;
public function setName($name) { $this->name = $name; } }
|
People.php
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
| <?php
namespace App\ProtoType;
class People implements Prototype {
private $name;
private $company;
public function __construct($name) { $this->name = $name; }
public function getCompany() { return $this->company; }
public function setCompany(Company $company) { $this->company = $company; }
public function shallowCopy() { return clone $this; }
public function deepCopy() { return unserialize(serialize($this)); }
}
|
Prototype.php
1 2 3 4 5 6 7 8 9
| <?php
namespace App\ProtoType;
interface Prototype{ public function shallowCopy();
public function deepCopy(); }
|
测试
TestPrototypr.php
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
| <?php
namespace Test;
require __DIR__ . '/../vendor/autoload.php';
use App\ProtoType\People; use App\ProtoType\Company;
$person1 = new People('赵帅帅'); $company = new Company(); $company->setName('China'); $person1->setCompany($company);
$person2 = $person1->deepCopy();
var_dump($person1, $person2);
$company->setName('种花家'); var_dump($person1, $person2);
$person2Com = $person2->getCompany(); $person2Com->setName('大中华'); var_dump($person1, $person2);
|