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

 

總結:

  • 裝飾器模式就是爲已有功能動態地添加更多功能地一種方式。當系統須要新功能時,這些新加入的功能僅僅是爲了知足一些特定狀況下才會執行的特殊行爲的須要。這時,裝飾器模式提供了一個很是好的解決方案,它把每一個要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的對象,所以,但須要執行特殊行爲時,客戶端代碼就能夠在運行時根據須要有選擇地、按順序地使用裝飾功能包裝對象了。
  • 裝飾器模式把類中地裝飾功能從類中移除,簡化了原有的類。
  • 有效地把類的核心職責和裝飾功能區分開了。並且能夠去除相關類中重複的裝飾邏輯。
相關文章
相關標籤/搜索