PHP设计模式—装饰器模式

 

定义:

装饰器模式(Decorator):动态的给一个对象添加一些额外的职责,就增长功能来讲,装饰器比生成子类更加灵活。php

 

结构:

  • Component:定义一个对象接口,能够给这些对象动态地添加职责。
  • ConcreteComponent:定义了一个具体的对象,也能够给这个对象添加一些职责。
  • Decorator:装饰抽象类,继承了 Component ,从外类来扩展 Component 类的功能,但对于 Component 来讲,是无需知道 Decorator 的存在的。
  • ConcreteDecorator:具体的装饰对象,起到给 Component 添加职责的功能。

 

代码实例:

这里以一个游戏角色为例,角色自己自带基础攻击属性,也能够经过额外的武器装备增长属性值。这里的装备武器就是动态的给角色添加额外的职责。
一、角色Role.php,对应Componentthis

/**
 * 角色,抽象类
 * Class Role
 */
abstract class Role
{
    /**
     * @return mixed
     */
    abstract public function getName();

    /**
     * @return mixed
     */
    abstract public function getAggressivity();
}

二、武器Arms.php,对应ConcreteComponentspa

/**
 * 武器,继承抽象类
 * Class Arms
 */
class Arms extends Role
{
    /**
     * 基础攻击力
     * @var int
     */
    private $aggressivity = 100;

    /**
     * @return string
     */
    public function getName()
    {
        // TODO: Implement getName() method.
        return '基础攻击值';
    }

    /**
     * @return int
     */
    public function getAggressivity()
    {
        // TODO: Implement getAggressivity() method.
        return $this->aggressivity;
    }

}

三、装饰抽象类RoleDecorator.php,对应Decoratorcode

/**
 * 装饰抽象类
 * Class RoleDecorator
 */
abstract class RoleDecorator extends Role
{
    /**
     * @var Role
     */
    protected $role;

    /**
     * RoleDecorator constructor.
     * @param Role $role
     */
    public function __construct(Role $role)
    {
        $this->role = $role;
    }
}

四、剑Sword.php,对应ConcreteDecorator对象

/**
 * 剑,具体装饰对象,继承装饰抽象类
 * Class Sword
 */
class Sword extends RoleDecorator
{
    /**
     * @return mixed|string
     */
    public function getName()
    {
        // TODO: Implement getName() method.
        return $this->role->getName() . '+斩妖剑';
    }

    /**
     * @return int|mixed
     */
    public function getAggressivity()
    {
        // TODO: Implement getAggressivity() method.
        return $this->role->getAggressivity() + 200;
    }
}

五、枪Gun.php,对应ConcreteDecoratorblog

/**
 * 枪,具体装饰对象,继承装饰抽象类
 * Class Gun
 */
class Gun extends RoleDecorator
{
    /**
     * @return mixed|string
     */
    public function getName()
    {
        // TODO: Implement getName() method.
        return $this->role->getName() . '+震天戟';
    }

    /**
     * @return int|mixed
     */
    public function getAggressivity()
    {
        // TODO: Implement getAggressivity() method.
        return $this->role->getAggressivity() + 150;
    }
}

六、调用继承

// 基础攻击值
$arms = new Arms();
echo $arms->getName();
echo $arms->getAggressivity() . '<br>';

// 基础攻击值+斩妖剑
$sword = new Sword(new Arms());
echo $sword->getName();
echo $sword->getAggressivity() . '<br>';

// 基础攻击值+震天戟
$gun = new Gun(new Arms());
echo $gun->getName();
echo $gun->getAggressivity() . '<br>';

// 基础攻击值+斩妖剑+震天戟
$person = new Gun(new Sword(new Arms()));
echo $person->getName();
echo $person->getAggressivity() . '<br>';

七、结果:接口

基础攻击值100
基础攻击值+斩妖剑300
基础攻击值+震天戟250
基础攻击值+斩妖剑+震天戟450

 

总结:

  • 装饰器模式就是为已有功能动态地添加更多功能地一种方式。当系统须要新功能时,这些新加入的功能仅仅是为了知足一些特定状况下才会执行的特殊行为的须要。这时,装饰器模式提供了一个很是好的解决方案,它把每一个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,所以,但须要执行特殊行为时,客户端代码就能够在运行时根据须要有选择地、按顺序地使用装饰功能包装对象了。
  • 装饰器模式把类中地装饰功能从类中移除,简化了原有的类。
  • 有效地把类的核心职责和装饰功能区分开了。并且能够去除相关类中重复的装饰逻辑。
相关文章
相关标签/搜索