原型模式其实更形象的来讲应该叫克隆模式。它主要的行为是对对象进行克隆,可是又把被克隆的对象称之为最初的原型,因而,这个模式就这样被命名了。说真的,从使用方式来看真的感受叫克隆模式更贴切一些。php
GoF定义:用原型实例指定建立对象的种类,而且经过拷贝这些原型建立新的对象git
GoF类图github
代码实现windows
abstract class Prototype {
public $v = 'clone' . PHP_EOL;
public function __construct() {
echo 'create' . PHP_EOL;
}
abstract public function __clone();
}
复制代码
首先咱们经过模拟的方式定义了一个原型,这里主要是模拟了__clone()这个方法。其实这是PHP自带的一个魔术方法,根本是不须要咱们去进行定义的,只须要在原型类中进行实现就能够了。当外部使用clone关键字进行对象克隆时,直接就会进入这个魔术方法中。在这个魔术方法里面咱们能够对属性进行处理,特别是针对引用属性进行一些独特的处理。在这个例子中,咱们只使用了一个值类型的变量。没法体现出引用类型的问题,咱们将在后面的实例中演示对引用类型变量的处理。设计模式
class ConcretePrototype1 extends Prototype {
public function __clone() {
}
}
class ConcretePrototype2 extends Prototype {
public function __clone() {
}
}
复制代码
模拟的具体实现的原型,其实就是主要去具体的实现__clone()方法。后面咱们看具体的例子时再说明。数组
class Client {
public function operation() {
$p1 = new ConcretePrototype1();
$p2 = clone $p1;
echo $p1->v;
echo $p2->v;
}
}
$c = new Client();
$c->operation();
复制代码
客户端使用clone来复制p2也具备相同的$v属性。微信
咱们的手机操做系统(也能够想象一下PC电脑的操做系统),都是怎样安装到设备中呢?其实都是不停的复制拷贝最初的那一套系统。用微软的例子很是好说明这个问题,当年微软可以成为一个帝国,其实也是由于他不停的将winodws操做系统拷贝复制到光盘中,而后卖给千家万户(固然,这里没中国什么事儿)。而中国市场呢,大量的高手破解了windows以后也是由这一份文件不停的复制拷贝才装到了咱们的电脑中。手机、智能设备等各种产品的操做系统、软件都是如此。一次开发无限拷贝正是软件行业暴利的缘由。毕竟咱们的系统也是由很多的工程师日以继夜的996在Android原生系统的基础上开发出来的,赶忙不断的复制到即将出厂的手机上吧!!学习
完整代码:github.com/zhangyue050…this
一样仍是拿手机来讲事儿,此次咱们是根据不一样的运营商须要去开发一批定制机,也就是套餐机。这批手机说实话都并无什么不一样,大部分都是相同的配置,可是运营商系统不一样,并且偶尔有一些型号的CPU和内存也可能存在不一样。这个时候,咱们就能够用原型模式来进行快速的复制而且只修改一部分不相同的地方啦。spa
原型模式生产手机类图
<?php
interface ServiceProvicer {
public function getSystem();
}
class ChinaMobile implements ServiceProvicer {
public $system;
public function getSystem(){
return "中国移动" . $this->system;
}
}
class ChinaUnicom implements ServiceProvicer {
public $system;
public function getSystem(){
return "中国联通" . $this->system;
}
}
class Phone {
public $service_province;
public $cpu;
public $rom;
}
class CMPhone extends Phone {
function __clone() {
// $this->service_province = new ChinaMobile();
}
}
class CUPhone extends Phone {
function __clone() {
$this->service_province = new ChinaUnicom();
}
}
$cmPhone = new CMPhone();
$cmPhone->cpu = "1.4G";
$cmPhone->rom = "64G";
$cmPhone->service_province = new ChinaMobile();
$cmPhone->service_province->system = 'TD-CDMA';
$cmPhone1 = clone $cmPhone;
$cmPhone1->service_province->system = 'TD-CDMA1';
var_dump($cmPhone);
var_dump($cmPhone1);
echo $cmPhone->service_province->getSystem();
echo $cmPhone1->service_province->getSystem();
$cuPhone = new CUPhone();
$cuPhone->cpu = "1.4G";
$cuPhone->rom = "64G";
$cuPhone->service_province = new ChinaUnicom();
$cuPhone->service_province->system = 'WCDMA';
$cuPhone1 = clone $cuPhone;
$cuPhone1->rom = "128G";
$cuPhone1->service_province->system = 'WCDMA1';
var_dump($cuPhone);
var_dump($cuPhone1);
echo $cuPhone->service_province->getSystem();
echo $cuPhone1->service_province->getSystem();
复制代码
说明
原型模式虽然日常用得很少,可是学习以后发现还真是挺有用的,特别是须要大量的重复对象时,能够大大节约新建对象的资源需求,之后仍是须要多多练习早日应用在实际的业务场景中。下一个又会是谁呢?别急别急,先去下个馆子,厨师、服务员、顾客,这三个要素就能组成一个神奇的模式:命令模式