php设计模式讲解,细致入微地讲解php设计模式:原型模式 - 翟码农技术博客

先抛开程序观念,通过一个简单的例子,来说明一下原型设计模式的好处:

我们慢慢用键盘打字,写了一封邮件。发出去后,发现有些人漏发了,要再发一次。接下来,你会直接复制刚才发的邮件内容,而不是从头开始重新写邮件,复制过来的邮件内容,你发觉里面的称呼,不适合当前的收件人,你还可以去修改邮件内容,但这并不会影响你刚才已经发出去的邮件。其中复制内容、可修改就是本文要讲的原型设计模式的好处。

原型设计模式的好处:创建快,可修改

废话不多说,下面直接结合程序代码,再来理解一下这个原型设计模式。<?php

//轮胎类

class Wheel{

//轮胎半径

private $radius = 10;

public function setRadius($value){

$this->radius = $value;

}

}

//车门类

class Door{

}

//小汽车类

class Car{

private $wheel;

private $door;

//车内温度

private $temperature;

public function __construct(Wheel $wheel, Door $door)

{

$this->wheel = $wheel;

$this->door = $door;

echo "--- new a car construct ----
";

$this->temperature = 30;

}

public function setTemperature($newValue){

$this->temperature = $newValue;

}

}

$wheel = new Wheel();

$door = new Door();

$car1 = new Car($wheel, $door);

$car2 = clone $car1; //拷贝原型对象

$car2->setTemperature(25);

var_dump($car1);

var_dump($car2);

上面程序在浏览器打印结果如下:--- new a car construct ----

F:\wamp\www\design\prototype\clone.php:49:

object(Car)[3]

private 'wheel' =>

object(Wheel)[1]

private 'radius' => int 10

private 'door' =>

object(Door)[2]

private 'temperature' => int 30

F:\wamp\www\design\prototype\clone.php:50:

object(Car)[4]

private 'wheel' =>

object(Wheel)[1]

private 'radius' => int 10

private 'door' =>

object(Door)[2]

private 'temperature' => int 25

原型设计模式就是通过拷贝(clone)原型对象来新建对象,而不是通过new关键字来创建对象。

有什么好处?

从上面打印结果就可以看出来:1. clone对象,不用执行原型对象的构造函数。对应“创建快”的优点

解析:上面输出的new a car construct 内容,是new Car类时执行构造函数时输出的。构造函数里面的工作,就类似上面例子中的打字写信的过程。clone对象,就不会执行原型类Car的构造函数,就相当于省掉了重新打字写信的过程。

2.新对象属性可修改,不会影响其它同类对象。对应“可修改”的优点

解析:上面输出就可以看出,car2对象车内温度设置为25摄氏度后,car1对象车内温度仍然是30度,并不会跟着变化。

从“可修改”的优点出发,拷贝还可以分为“深拷贝”和“浅拷贝”。上面的代码实现的是“浅拷贝”,实际应用大多都是“深拷贝”。

那么什么是深拷贝和浅拷贝呢?

先继续利用上面程序,来说说浅拷贝是怎么回事儿?

在上面程序末尾添加如下两行代码:$wheel->setRadius(20);

var_dump($car2);

打印结果如下:F:\wamp\www\design\prototype\clone.php:52:

object(Car)[4]

private 'wheel' =>

object(Wheel)[1]

private 'radius' => int 20

private 'door' =>

object(Door)[2]

private 'temperature' => int 25

你关注下车轮半径值,由10变为20了,有什么问题么?

......

问题就在于:

我修改的wheel类是用于创建car1对象的,却影响到了car2对象。通俗点说,我在改一辆车的轮胎大小,另一辆车的轮胎大小也跟着同样变化了,这就是浅拷贝所带来的问题。

翟码农自己给浅拷贝下一个定义:浅拷贝:针对原对象的属性和方法,所有拷贝类拥有独立的一份。但对于依赖的类对象,所有拷贝类依赖的类对象都是同一个(即依赖的类对象在内存里都是共同的区域)。

深拷贝就是解决浅拷贝的问题而产生的概念。

php里深拷贝如何实现呢?

在上面程序里Car类里添加如下方法:public function __clone()

{

echo "--- enter clone function ---
";

$this->wheel = clone $this->wheel;

$this->door = clone $this->door;

}

__clone是魔术方法,在使用clone关键字时,会自动调用原型类的这个方法。

再看上面程序里car2对象的内容,就会发现车轮半径是10了。在末尾再次打印car1对象内容,发现车轮半径改成20了。

这就说明,此时car1对象和car2对象依赖的车轮类对象都是独立的了。这就是我们所说的深拷贝。

原型设计模式的应用场景:

通篇下来,就可以理解,当需要大量创建某种类的实例时,就可以采用此模式,避免执行构造函数,减少内存消耗,节省时间,即加快了实例的生成。

本文为翟码农个人博客里有关原型设计模式的原创文章,转载请注明出处:http://www.zhai14.com/blog/design-pattern-of-prototype.html

2020年03月25日 18:27文章创建

2020年03月26日 00:49文章发布

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值