概述

原型模式( ), 是获取对象的一种设计模式. 设计思想是通过复制(克隆)已有对象, 得到新的对象. 而这个已有对象, 就是复制(克隆)而形成才新对象的原型. 故称之原型模式.

核心语法, 就是clone.

使用克隆获取新对象的方式的优势通常是, 在实例化对象相对复杂时, 通常指的是需要做大量的构造初始化计算时, 可以采用克隆(复制)的方式得到新对象, 提升获取对象的效率.

代码展示

定义可以添加原型和利用原型克隆对象的方法

class Factory
{
    private static $prototypeList = [];
    public static function addPrototype($obj)
    {
        static::$prototypeList[get_class($obj)] = $obj;
    }
    public static function getObject($class)
    {
        return clone static::$prototypeList[$class];
    }
}

将需要克隆的对象原型加入工厂

class Hero
{
    private $objectType;
    public function __clone()
    {
        $this->objectType = clone $this->objectType;
    }
}
class Beauty
{
}
Factory::addPrototype(new Hero());
Factory::addPrototype(new Beauty());

需要对象时, 通常工厂克隆生成

$h1 = Factory::getObject('Hero');
$h2 = Factory::getObject('Hero');
$h3 = Factory::getObject('Hero');
$b1 = Factory::getObject('Beauty');

代码分析

工厂类的静态属性存储加入工厂的原型对象, 等待被克隆.

提供生成对象的接口(), 通过传递参数类名,获取对应的对象.

对象是通过clone而形成的.

采用该方法原型模式, 在new操作复杂(构造方法复杂)时, clone获取对象的效率会高些, 做了一个小测试:

class Hero
{
    private $name;
    private $gender;
    private $country;
    public function __construct()
    {
        $this->name = 'someName';
        $this->gender = 'someGender';
        $this->country = 'someCountry';
    }
}
$s = microtime(true);
for($i=0; $i<1000; ++$i) {
    $new[] = new Hero;
}
//0.0015060901641846
echo microtime(true) - $s, '
'; $hero = new Hero(); $s = microtime(true); for($i=0; $i<1000; ++$i) {    $clone[] = clone $hero; } // 0.00049400329589844 echo microtime(true) - $s, '
';

通过执行时间可看出, clone的效率会高些.

但是, 如果去掉构造方法, 则new的效率会高些. 当前PHP版本php5.6

深浅克隆

在执行clone时, PHP默认采用浅克隆, 就是如果是对象类型的属性, 则仅仅是引用复制, 而不是复制对象本身.

如果需要将对象本身也同时克隆. 则需要定义对象的()方法, 对对象类型的属性做进一步的clone操作.

class Hero
{
    private $objectType;
    public function __clone()
    {
        $this->objectType = clone $this->objectType;
    }
}

结语

小韩说理,一家之言原型模式, 请拍砖.

准备了一个系列的设计模式文章. 会逐一发表, 如有需要, 请持续关注.

如果方便, 请帮忙转发.

原型模式类图_原型模式优缺点_原型模式

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注