php-装饰器模式实现

php-装饰器模式实现

概述

装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。根据翻译的不同,装饰模式也有人称之为“油漆工模式”,它是一种对象结构型模式。

我们这里还是以摩托车制造为例。现在我们需要对踏板摩托车进行自定义配件的装饰以及我们希望对其进行第三方质检操作。那么我们就可以用到装饰器模式

模式结构

以本文实例代码为参考

  1. MotorcycleProduce-摩托组装抽象类:建立摩托组装标准工艺
  2. MotocycleProduct-摩托车产品本身
  3. MotorcycleScooter-踏板摩托车
  4. MotorDecorator-抽象摩托车装饰器类
  5. MotorDecoratorA-装饰器A
  6. MotorDecoratorB-装饰器B

UML图例

在这里插入图片描述

代码实例

<?php 
namespace Decorator;
//抽象类-定义生产摩托车流水线标准  Target 目标类
interface  MotorcycleProduce 
{
    //发动机方法
    public function addEngine();
    //车身方法
    public function addBody();
    //车轮方法
    public function addWhell();
    //获取摩托
    public function getMotor();
}
//摩托车产品本身
class MotocycleProduct{
    private $motor = [
        "engine"=>"",
        "body"=>"",
        "whell"=>"",
        "bodyColor"=>"blue"
    ];
    //新增发动机零部件
    public function addEngine($engine){
        $this->motor["engine"] = $engine;
    }
    public function addBody($body){
        $this->motor["body"] = $body;
    }
    public function addWhell($whell){
        $this->motor["whell"] = $whell;
    }
    //获取完整摩托对象
    public function getMotor(){
        return $this->motor;
    }
}
class MotorcycleScooter implements MotorcycleProduce
{
    private $motor;
    public function __construct()
    {
        $this->motor = new MotocycleProduct();
    }
    function addEngine()
    {
        $this->motor->addEngine("踏板摩托-发动机已装好");
    }
    function addBody()
    {
        $this->motor->addBody("踏板摩托-车身已装好");
    }
    function addWhell()
    {
        $this->motor->addWhell("踏板摩托-车轮已装好");
    }
    function getMotor()
    {
        return $this->motor->getMotor();
    }
}
/**
 * 抽象摩托车装饰器类
 */
abstract class MotorDecorator implements MotorcycleProduce{
    protected $motor_cycle;
    public function __construct(MotorcycleProduce $motor_cycle){
        $this->motor_cycle = $motor_cycle;
    }
}
/**
 * 装饰器类-A
 */
class MotorDecoratorA extends MotorDecorator{
    public function addEngine(){
        $this->motor_cycle->addEngine();
    }
    public function addBody()
    {
        $this->motor_cycle->addBody();
    }
    public function addWhell()
    {
        $this->motor_cycle->addWhell();
    }
    public function getMotor()
    {
        $motor = $this->motor_cycle->getMotor();
        $motor["other"] = "个性化配件";
        return $motor;
    }
}
/**
 * 装饰器类
 */
class MotorDecoratorB extends MotorDecorator{
    public function checkMoto(){
        echo "摩托合规性检测-合规<br>";
    }
    public function addEngine(){
        $this->motor_cycle->addEngine();
    }
    public function addBody()
    {
        $this->motor_cycle->addBody();
    }
    public function addWhell()
    {
        $this->motor_cycle->addWhell();
    }
    public function getMotor()
    {
        $motor = $this->motor_cycle->getMotor();
        $this->checkMoto();
        return $motor;
    }
}
$motorScooter = new MotorcycleScooter();
$motorDecoratorA = new MotorDecoratorA($motorScooter);
$motorDecoratorA->addEngine();
$motorDecoratorA->addBody();
$motorDecoratorA->addWhell();
$motor = $motorDecoratorA->getMotor();
var_dump($motor);
echo "<br>";
$motorDecoratorB = new MotorDecoratorB($motorScooter);
$motorDecoratorB->addEngine();
$motorDecoratorB->addBody();
$motorDecoratorB->addWhell();
$motor = $motorDecoratorB->getMotor();
var_dump($motor);

模式分析

  • 使用装饰模式来实现扩展比继承更加灵活,它以对客户透明的方式动态地给一个对象附加更多的责任。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。
  • 相比继承,关联关系的主要优势在于不会破坏原有产品类的封装性,继承是一种耦合度将大的静态关系,扩展起来相对麻烦。不便于后期的维护。由于关联关系使系统具备较好的松耦合性。使得系统更加容易维护。

优缺点

装饰模式的优点:

  • 装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
  • 可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。
  • 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
  • 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”

装饰模式的缺点:

  • 装饰器模式下会产生很多小对象,这些对象的区别在于他们之间相互连接的方式有所不同。随着装饰类和小对象的增多将会增加系统的复杂度,从而导致了系统在学习和理解起来会相对困难。
  • 由于类的灵活的特性,也同时意味着装饰模式更容易出错,且不容易排错,对于多次装饰的对象,在排错时相对繁琐。

适用环境

在以下情况下可以使用装饰模式:

  • 需要动态的调整单个对象的职责。
  • 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。不能采用继承的情况主要有两类:第一类是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;第二类是因为类定义不能继承(如final类).
关注微信公众号(yuantanphp)
回复关键字 设计模式 可获取以下材料
《设计模式:可复用面向对象软件的基础》pdf版.
php设计模式23种实例实现php源码
在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冯伪猿

觉得文章不错?打赏支持一下吧。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值