zoukankan      html  css  js  c++  java
  • PHP设计模式—装饰器模式

    定义:

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

     

    结构:

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

     

    代码实例:

    这里以一个游戏角色为例,角色本身自带基础攻击属性,也可以通过额外的武器装备增加属性值。这里的装备武器就是动态的给角色添加额外的职责。
    1、角色Role.php,对应Component

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

    2、武器Arms.php,对应ConcreteComponent

    /**
     * 武器,继承抽象类
     * 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;
        }
    
    }

    3、装饰抽象类RoleDecorator.php,对应Decorator

    /**
     * 装饰抽象类
     * Class RoleDecorator
     */
    abstract class RoleDecorator extends Role
    {
        /**
         * @var Role
         */
        protected $role;
    
        /**
         * RoleDecorator constructor.
         * @param Role $role
         */
        public function __construct(Role $role)
        {
            $this->role = $role;
        }
    }

    4、剑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;
        }
    }

    5、枪Gun.php,对应ConcreteDecorator

    /**
     * 枪,具体装饰对象,继承装饰抽象类
     * 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;
        }
    }

    6、调用

    // 基础攻击值
    $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>';

    7、结果:

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

     

    总结:

    • 装饰器模式就是为已有功能动态地添加更多功能地一种方式。当系统需要新功能时,这些新加入的功能仅仅是为了满足一些特定情况下才会执行的特殊行为的需要。这时,装饰器模式提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,但需要执行特殊行为时,客户端代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
    • 装饰器模式把类中地装饰功能从类中移除,简化了原有的类。
    • 有效地把类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑。
  • 相关阅读:
    mybais 的映射文件,需要从poviderDao.java 的一个 方法 public getProvidersFactors(参数 ) 中传入多个参数到providerDao.xml中的两种方法
    mybatis映射文件,当从XXXDao.java中传入的参数是一个对象Provider的时候,那在XXXDao.xml中的Provider的属性id的时候需要怎么写
    AJAX概念及作用。 JQuery中关于AJAX的几个常用的函数
    js代码中的parent,top和self有什么区别
    JS window对象的top、parent、opener含义介绍
    登录为什么登陆什么都要验证码?验证码有什么用?没有验证码之后会有什么危害
    关于重定向RedirectAttributes的用法
    HTML meta标签总结与属性使用介绍 ,超详细,代例子
    jsp页面中的:<%@ page contentType="text/html; charset=utf-8" language="java"%>的作用及含义,超详细!
    mybatis和Dao映射的配置文件xml,中什么时候需要用resultType .什么时候用resultMap,及resultType和resultMap的区别
  • 原文地址:https://www.cnblogs.com/woods1815/p/12826090.html
Copyright © 2011-2022 走看看