装饰器模式(Decorator):动态的给一个对象添加一些额外的职责,就增长功能来讲,装饰器比生成子类更加灵活。php
这里以一个游戏角色为例,角色自己自带基础攻击属性,也能够经过额外的武器装备增长属性值。这里的装备武器就是动态的给角色添加额外的职责。
一、角色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