PHP设计模式:装饰器模式
前言
装饰器模式可以随心所欲动态的添加属性,最大程度上实现了灵活性
主要分为
- 被装饰的物品
- 装饰的组件
装饰器模式中,可以随意的将组件和被装饰品抽象
- 被装饰的物品抽象
- 装饰的组件抽象
- 两个一起抽象
- 两个都不抽象
- 爱怎么搞怎么搞
其中,带着抽象的代码示例为:
<?php
//声明一个装饰抽象类
abstract class Component
{
//定义一个操作
abstract public function operation();
}
class MyOperation extends Component
{
public function operation()
{
echo '这是要进行的操作' . PHP_EOL;
}
}
//声明一个装饰品抽象类继承装饰抽象类
abstract class Ornament extends Component
{
//声明一个受保护的变量用来挂载传入的实例
protected $mountClass;
//构造函数中把需要挂载的实例挂载到变量中
public function setMountClass($mountClass)
{
$this->mountClass = $mountClass;
}
//定义一个装饰行为,执行被挂载实例的operation()方法
public function operation()
{
if ($this->mountClass != null) {
$this->mountClass->operation();
}
}
}
//定义第一个装饰品
class OrnamentCreateA extends Ornament
{
//重写父类的装饰行为,但是重点是必须执行一次父类装饰行为
public function operation()
{
//执行完之后就是这个类需要装饰什么东西了,在这里可以装饰在前面,也可以装饰在后,可以随便折腾
echo '我是一个前置装饰器' . PHP_EOL;
parent::operation();//执行了父类的装饰行为
}
}
//定义第一个装饰品,这次来实验一下后置装饰器
class OrnamentCreateB extends Ornament
{
//重写父类的装饰行为,但是重点是必须执行一次父类装饰行为
public function operation()
{
parent::operation();//执行了父类的装饰行为
echo '我是一个后置装饰器' . PHP_EOL;
}
}
$MyOperation = new MyOperation();//实例化你的操作
$OrnamentA = new OrnamentCreateA();//实例化装饰品A
$OrnamentB = new OrnamentCreateB();//实例化装饰品B
//操作的顺序是将你的操作丢给一个装饰器,在装饰第二个的时候直接把第一个装饰器丢进去,以此类推
$OrnamentA->setMountClass($MyOperation);
$OrnamentB->setMountClass($OrnamentA);
$OrnamentB->operation();
输出:
image.png
如果不抽象的话,也可以直接继承使用
//声明一个人类
class People
{
//声明一个变量用来挂载名字
protected $name;
public function __construct($name)
{
$this->name = $name;
}
//定义人类有穿衣服的功能
public function dress()
{
echo $this->name . "开始穿衣服了:";
}
}
//定义一个装饰类
class Finery
{
protected $people;
public function bindPeople($people)
{
$this->people = $people;
}
public function dress()
{
if ($this->people != null) {
//这里其实调用的是人的dress
$this->people->dress();
}
}
}
//定义一个草裙
class Hula extends Finery
{
public function dress()
{
parent::dress();
echo '穿上了草裙' . PHP_EOL;
}
}
//定义一个棍子
class Stick extends Finery
{
public function dress()
{
parent::dress();
echo '举着一根超大的棍子' . PHP_EOL;
}
}
//定义一个鞋子
class Shoes extends Finery
{
public function dress()
{
parent::dress();
echo '穿一双马靴' . PHP_EOL;
}
}
$people = new People('小明');
//实例化草裙,棍子,和鞋子
$hula = new Hula();
$stick = new Stick();
$shoes = new Shoes();
//开始装饰
$hula->bindPeople($people);
$stick->bindPeople($hula);
$shoes->bindPeople($stick);
$shoes->dress();
输出:
image.png
光是看是很难理解的。最好的办法是动手自己撸一次!