PHP设计模式(六)之PHP实现原型模式

作者: 温新

分类: 【设计模式】

阅读: 1925

时间: 2020-01-05 06:45:32

一、什么是原型模式
原型模式:原型模式用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

意图:复制已有对象,不用依赖所属类

二、使用原型模式的原因

1)普通方式创建对象通过new Xxx();如果每一次都通过new来创建一个对象,并且在new时还要进行初始化化工作,,它的开销非常大。

2)原型模式最大不同之处在于它是先创建好一个原型对象,然后通过clone这个原型对象来实现新对象的创建,如此省去了重复的初始化工作。

解释:

案例一:当厨师在做清蒸鲈鱼这道菜时,都有固定的步骤,每一步做什么,第二步做什么...当只有一个客户点了这道菜时,好吧,按照步骤做吧。当遇到酒席时,每一桌都有清蒸鲈鱼这道菜时,还按照第一步、第二步...来做,显然是无法完成任务的。那么厨师要怎么样才能完成任务?厨师就在想,每一个步骤是一样的,那能不能复制呢?当然可以了,于是厨师先不做清蒸鲈鱼了,先创建一个清蒸鲈鱼原型对象,然后批量生产。

案例二:《大话西游》中至尊宝对战牛魔王,至尊宝拔出猴毛生产出N多个自己,这也是原型模式。

三、原型模式结构

抽象原型角色(Prototype):声明一个克隆自身的接口

具体原型角色(Concrete Prototype):实现一个克隆自身的操作

四、深、浅拷贝

深拷贝:

被拷贝对象的所有的变量都含有与原来对象相同的值,除了那些引用其他对象的变量。那些引用其他对象的变量将指向一个被拷贝的新对象,而不再是原有那些被引用对象。

即深拷贝把要拷贝的对象所引用的对象也都拷贝了一次,而这种对被引用到的对象拷贝叫做间接拷贝。

浅拷贝:

拷贝对象的所有变量都含有与原对象相同的值,而且对其他对象的引用仍然是指向原来的对象。

即浅拷贝只负责当前对象实例,对引用的对象不做拷贝。

利用序列化来做深拷贝:

利用序列化来做深拷贝,把对象写到流里的过程是序列化(Serilization)过程,但在业界又将串行化这一过程形象的称为“冷冻”或“腌咸菜”过程;

而把对象从流中读出来的过程则叫做反序列化(Deserialization)过程,也称为“解冻”或“回鲜”过程。

在PHP中使用serialize和unserialize函数实现序列化和反序列化

五、代码实现

// 抽象原型角色(Prototype)
SteamedPerchPrototype.php

<?php


/**
* 清蒸鲈鱼原型        =>  抽象原型角色
*
**/
interface SteamedPerchPrototype
{
    // 浅复制
    public function shallowCopy();

    // 深复制
    public function deepCopy();
}

// 具体原型角色(Concrete Prototype)
ConcreteSteamedPerchPrototype.php <?php

/**
* 具体清蒸鲈鱼原型  ==> 具体原型角色
*
**/

class ConcreteSteamedPerchPrototype implements SteamedPerchPrototype
{
    // 清蒸鲈鱼
    public $name;

    // 初始化菜名
    public function __construct($name)
    {
        $this->name = $name;
    }

    // 设置菜名
    public function setName($name)
    {
        return $this->name = $name;
    }

    // 获取菜名
    public function getName()
    {
        return $this->name;
    }

    // 实现浅复制
    public function shallowCopy()
    {
        return clone $this;
    }

    // 实现深复制
    public function deepCopy()
    {
        // 通过序列化实现深度复制
        $serializeObj = serialize($this);
        return unserialize($serializeObj);
    }
}

SteamedPerch.php

<?php

class SteamedPerch
{
    public $string;
}

// 实现
index.php

<?php

require_once './SteamedPerchPrototype.php';
require_once './ConcreteSteamedPerchPrototype.php';
require_once './SteamedPerch.php';

//$a = new ConcreteSteamedPerchPrototype('清蒸鲈鱼');

$SteamedPerchObj = new SteamedPerch();
$SteamedPerchObj->string = '鱼';

// 浅复制
$a = new ConcreteSteamedPerchPrototype($SteamedPerchObj);
$b = $a->shallowCopy();


var_dump($a->getName());
echo '<br>';
var_dump($b->getName());
echo '<br>';

// 深复制
$c = $a->deepCopy();
var_dump($c->getName());
echo '<br>';
$SteamedPerchObj->string = '1231231231';
$c = $a->deepCopy();
var_dump($c->getName());

我是夕阳何处寻,期待和优秀的你一起同行!

夕阳何处寻

2020年1月5日

请登录后再评论