原型模式主要用于创建重复的对象;
目的是使用 clone 对象来减少 new 对象的开销;
如果某个场景需要多次实例化一个类;
那就可以尝试用原型模式优化;
在 php 中使用原型模式是很简单的;
毕竟 php 是世界上最好的语言;
我们只需要 clone 就行了;
但是 clone 有一些问题;
我们下面在代码中讲;
抽象的 __clone() 方法;
我们先来个 clone 节省资源的直观示例;
造个车;
Car.php
<?php
namespace Baijunyao\DesignPatterns\Prototype;
/**
* Class Car
* @package Baijunyao\DesignPatterns\Prototype
*/
class Car
{
/**
* 车名
*
* @var
*/
public $name;
/**
* 设置车名
*
* @param $name
*/
public function setName($name)
{
$this->name = $name;
}
}
驾驶汽车;
ShallowDrive.php
<?php
namespace Baijunyao\DesignPatterns\Prototype;
/**
* Class ShallowDrive
* @package Baijunyao\DesignPatterns\Prototype
*/
class ShallowDrive
{
private $car;
/**
* Drive constructor.
*/
public function __construct()
{
echo '准备完成';
}
/**
* 选择要开的车
*
* @param $car
*/
public function setCar($car)
{
$this->car = $car;
}
public function show()
{
echo '开始驾驶'.$this->car->name;
echo '<br>';
}
}
运行;
index.php
<?php
namespace Baijunyao\DesignPatterns\Prototype;
require __DIR__.'/../vendor/autoload.php';
/**
* 客户端
*
* Class Client
* @package Baijunyao\DesignPatterns\Prototype
*/
class Client
{
/**
* 浅复制
*/
public function shallowCopy()
{
$car = new Car();
$car->name = '特斯拉';
$shallowDrive = new ShallowDrive();
$shallowDrive->setCar($car);
$shallowDrive->show();
$cloneDrive = clone $shallowDrive;
$cloneDrive->show();
}
}
$client = new Client();
$client->shallowCopy();
从运行结果可以看出;
原本的流程需要先 new Car();
然后new Drive();
得到的 $shallowDrive 先执行__contract() 然后执行 show();
而克隆出来的$cloneDrive 不要 new Car();
不要 __contract() ;
直接 show() 带回家 ;
相当于 $cloneDrive 不用做准备工作直接就能驾驶起来跑了;
但是问题也显而易见;
我们不要在 __contract() 中做具体的工作;
而且需要注意的是 clone 是浅复制;
也就是说 $cloneDrive 的 car 和 $shallowDrive 的 car 是一个引用;
如果我们改变了 $car ;
$cloneDrive 也会被改变;
index.php
<?php
namespace Baijunyao\DesignPatterns\Prototype;
require __DIR__.'/../vendor/autoload.php';
/**
* 客户端
*
* Class Client
* @package Baijunyao\DesignPatterns\Prototype
*/
class Client
{
/**
* 浅复制
*/
public function shallowCopy()
{
$car = new Car();
$car->name = '特斯拉';
$shallowDrive = new ShallowDrive();
$shallowDrive->setCar($car);
$shallowDrive->show();
$cloneDrive = clone $shallowDrive;
$cloneDrive->show();
echo '<hr>';
$car->name = '凯迪拉克';
$shallowDrive->show();
$cloneDrive->show();
}
}
$client = new Client();
$client->shallowCopy();
如果我们想要一个深复制;
$shallowDrive 和 $cloneDrive 之间不再有引用一个 car;
再建个 DeepDrive.php ;
核心是 __clone 方法;
<?php
namespace Baijunyao\DesignPatterns\Prototype;
/**
* Class DeepDrive
* @package Baijunyao\DesignPatterns\Prototype
*/
class DeepDrive
{
private $car;
/**
* Drive constructor.
*/
public function __construct()
{
echo '准备完成';
}
/**
* 选择要开的车
*
* @param $car
*/
public function setCar($car)
{
$this->car = $car;
}
public function show()
{
echo '开始驾驶'.$this->car->name;
echo '<br>';
}
public function __clone()
{
$this->car = clone $this->car;
}
}
运行;
index.php
<?php
namespace Baijunyao\DesignPatterns\Prototype;
require __DIR__.'/../vendor/autoload.php';
/**
* 客户端
*
* Class Client
* @package Baijunyao\DesignPatterns\Prototype
*/
class Client
{
/**
* 浅复制
*/
public function shallowCopy()
{
$car = new Car();
$car->name = '特斯拉';
$shallowDrive = new ShallowDrive();
$shallowDrive->setCar($car);
$shallowDrive->show();
$cloneDrive = clone $shallowDrive;
$cloneDrive->show();
echo '<hr>';
$car->name = '凯迪拉克';
$shallowDrive->show();
$cloneDrive->show();
}
/**
*
*/
public function deepCopy()
{
$car = new Car();
$car->name = '特斯拉';
$deepDrive = new DeepDrive();
$deepDrive->setCar($car);
$deepDrive->show();
$cloneDrive = clone $deepDrive;
$cloneDrive->show();
echo '<hr>';
$car->name = '凯迪拉克';
$deepDrive->show();
$cloneDrive->show();
}
}
$client = new Client();
$client->shallowCopy();
echo '<br>-----------------------------<br>';
$client->deepCopy();
如我们所愿;
$cloneDrive 并没有随 $deepDrive 的 car 变化;
创建型的设计模式就算讲完了;
下篇文章我们将开始结构型的设计模式;
github示例:https://github.com/baijunyao/design-patterns/tree/master/Prototype
本文为白俊遥原创文章,转载无需和我联系,但请注明来自白俊遥博客https://baijunyao.com 欢迎捐赠赞赏加入组织创建QQ群及捐赠渠道
最新评论