设计模式
一、介绍
装饰模式是一种结构型设计模式,它允许你通过将对象和对象装饰器分离来扩展对象的功能。装饰模式是一种动态地添加功能的方法,它允许你在运行时根据需要添加或删除对象的功能。
举个例子:很多游戏中的人物都是可以携带装备的,比如剑,盾,盔甲,戒指等。在获得这些装备后,玩家可以随意的穿戴卸下,最后形成不同的装饰效果。
二、优缺点
优点:
- 可以在运行时添加或删除对象的功能。
- 无需创建新子类即可扩展对象的行为。
- 可以用多个装饰封装对象来组合多种行为。
- 单一职责原则:可以将实现了许多不同行为的一个大类拆分为多个较小的类。
缺点:
- 在封装器栈中删除特定封装器比较困难。
- 实现行为不受装饰栈顺序影响的装饰比较困难。
- 各层的初始化配置代码看上去可能会很不友好。
三、核心结构
- Component(组件):定义了基本组件接口,有被装饰器修改的操作方法。
- ConcreteComponent(具体组件):组件的具体实现类。
- Decorator(装饰器):基类,遵循与其他组件相同的接口。这个类的主要目的是为所有具体组件的装饰器定义包装接口。
- ConcreteDecorator(具体装饰器):具体装饰器调用包装对象并以某种方式改变其结果。
四、代码实现
1、Component(组件):定义了基本组件接口,有被装饰器修改的操作方法。
<?php
/**
* Created by PhpStorm
* Author: fengzi
* Date: 2024/6/26
* Time: 10:37
*/
namespace app\admin\service\mode\decorator;
/**
* 定义一个接口,用于装饰器类实现
*/
interface Component
{
public function operation();
}
2、ConcreteComponent(具体组件):组件的具体实现类。
<?php
/**
* Created by PhpStorm
* Author: fengzi
* Date: 2024/6/26
* Time: 10:40
*/
namespace app\admin\service\mode\decorator;
/**
* 具体组件,实现Component接口
*/
class ConcreteComponent implements Component
{
/**
* @return string
* @Author: fengzi
* @Date: 2024/6/26 10:40
*/
public function operation()
{
// TODO: Implement operation() method.
return "魔法师";
}
}
3、Decorator(装饰器):基类,遵循与其他组件相同的接口。这个类的主要目的是为所有具体组件的装饰器定义包装接口。
<?php
/**
* Created by PhpStorm
* Author: fengzi
* Date: 2024/6/26
* Time: 10:41
*/
namespace app\admin\service\mode\decorator;
/**
* 定义一个装饰器类,用于包装其他类
*/
class Decorator implements Component
{
protected Component $component;
public function __construct(Component $component)
{
$this->component = $component;
}
public function operation()
{
return $this->component->operation();
}
}
4、ConcreteDecorator(具体装饰器):具体装饰器调用包装对象并以某种方式改变其结果。
<?php
/**
* Created by PhpStorm
* Author: fengzi
* Date: 2024/6/26
* Time: 10:43
*/
namespace app\admin\service\mode\decorator;
class ConcreteDecoratorA extends Decorator
{
public function operation()
{
return parent::operation() . " 装备上了[魔法棒] ";
}
}
<?php
/**
* Created by PhpStorm
* Author: fengzi
* Date: 2024/6/26
* Time: 10:43
*/
namespace app\admin\service\mode\decorator;
class ConcreteDecoratorB extends Decorator
{
public function operation()
{
return parent::operation() . " 装备上了[魔法袍] ";
}
}
5、客户端调用
<?php
/**
* Created by PhpStorm
* Author: fengzi
* Date: 2024/6/26
* Time: 10:47
*/
namespace app\admin\controller\mode\decorator;
use app\admin\service\mode\decorator\ConcreteComponent;
use app\admin\service\mode\decorator\ConcreteDecoratorA;
use app\admin\service\mode\decorator\ConcreteDecoratorB;
/**
* 客户端
*/
class ClientController
{
public function index()
{
/**
* 不用装饰器的情况下人物无任何的装备。
*/
$base = new ConcreteComponent();
echo $base->operation();
echo PHP_EOL."\n";
/**
* 使用装饰器的情况下人物添加新的装备
*/
$decoratorA = new ConcreteDecoratorA($base);
/**
* 人物添加新的装备
*/
$decoratorB = new ConcreteDecoratorB($decoratorA);
echo $decoratorB->operation();
die();
}
}
6、调用结果