• PHP设计模式-装饰器模式


    1.概念:

      装饰器模式又叫做装饰者模式,是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。传统的编程模式都是子类继承父类实现方法的重载,使用装饰器模式,只需添加一个新的装饰器对象,更加灵活,避免类数目和层次过多。

    2.角色:

    Component(被装饰对象基类):定义一个对象接口,以规范准备接受附加责任的对象。

    ConcreteComponent(具体被装饰对象):具体组件角色,即将要被装饰增加功能的类。

    Decorator(装饰者基类):装饰器接口。

    ConcreteDecorator(具体的装饰者类):具体装饰器,向组件添加职责。

    3.实例:

    需求描述

    一个餐饮系统,包含主食和配菜,主食和配菜分别包含不同类别和不同价位。为了保证系统的可扩展性(修改价格,增加或减少主食/配菜种类等需求),使用装饰器模式。

    组织架构:

      

    代码展示:

     LibsComponent.php

    <?php
    namespace Libs;
    /**
     * 被装饰对象基类
     * */
    interface Component
    {
        /**
         * 计算所需费用
         * */
        public function cost();
    }

     LibsConcreteComponentBun.php

    <?php
    namespace Libs;
    
    /**
     * 定义具体被装饰对象,这里是主食之包子
     * */
    class ConcreteComponentBun implements Component
    {
        public function __construct()
        {
            echo "Oh,There is the construct of ConcreteComponentBun.</br>";
        }
        public function cost()
        {
            echo "There is the function of ConcreteComponentBun named cost. <br/>";
            return 15.00;
        }
    }

     LibsDecorator.php

    <?php
    namespace  Libs;
    /**
     * 装饰器接口
     * */
    class Decorator implements Component
    {
        public function __construct()
        {
            $this->_name = 'Decorator';
        }
        public function cost()
        {
            return 1.00;
        }
    
    }

     LibsConcreteDecoratorSalad.php

    <?php
    namespace Libs;
    
    class ConcreteDecoratorSalad extends Decorator
    {
        public $_component;
        public function __construct($component)
        {
            echo "Oh,There is the construct of ConcreteDecoratorSalad.</br>";
            
            if($component instanceof Component){
                $this->_component = $component;
            } else {
                exit('Failure');
            }
        }
        public function cost()
        {
            echo "There is the function of ConcreteDecoratorSalad named cost. <br/>";
            return $this->_component->cost()+10.00;
        }
    }

      LibsConcreteDecoratorSoup.php

    <?php
    namespace Libs;
    
    class ConcreteDecoratorSoup extends Decorator
    {
        public $_component;
        public function __construct($component)
        {
            echo "Oh,There is the construct of ConcreteDecoratorSoup.</br>";
            if($component instanceof Component){
                $this->_component = $component;
            } else {
                exit('Failure');
            }
        }
        public function cost()
        {
            echo "There is the function of ConcreteDecoratorSoup named cost. <br/>";
            return $this->_component->cost()+5.00;
        }
    
    }

    LibsUseDecorator.php

    <?php
    namespace Libs;
    
    class UseDecorator
    {
        public static function index()
        {
            
            $bun = new ConcreteComponentBun();
            $cost = $bun->cost();
            echo "The cost is {$cost} <br>";
            echo "_________________________________________________</br>";
            
            $salad_bun = new ConcreteDecoratorSalad($bun);
            $cost = $salad_bun->cost();
            echo "The cost is {$cost} <br>";
            echo "_________________________________________________</br>";
            
            $soup_bun = new ConcreteDecoratorSoup($bun);
            $cost = $soup_bun->cost();
            echo "The cost is {$cost} <br>";
            echo "_________________________________________________</br>";
            
        }
    }

     调用

    LibsUseDecorator::index();

    结果:

    Oh,There is the construct of ConcreteComponentBun.
    There is the function of ConcreteComponentBun named cost. 
    The cost is 15 
    _________________________________________________
    Oh,There is the construct of ConcreteDecoratorSalad.
    There is the function of ConcreteDecoratorSalad named cost. 
    There is the function of ConcreteComponentBun named cost. 
    The cost is 25 
    _________________________________________________
    Oh,There is the construct of ConcreteDecoratorSoup.
    There is the function of ConcreteDecoratorSoup named cost. 
    There is the function of ConcreteComponentBun named cost. 
    The cost is 20 
    _________________________________________________
    

      

    4.优缺点

    • 优点:

        1). Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
        2). 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

    • 缺点:

        1). 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
        2). 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
        3). 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

    推荐阅读>>

    PHP设计模式之装饰者模式

    PHP设计模式——装饰器模式

    PHP设计模式之装饰者模式

    PHP设计模式之装饰器模式

    PHP设计模式--装饰器模式

    php设计模式-装饰器模式

    PHP 设计模式系列 —— 装饰器模式(Decorator)

    php设计模式之———装饰器模式

    装饰器模式 应用场景

  • 相关阅读:
    记录五年社畜萌新尝试将静态网站在docker上使用nginx部署
    C# 按照比重来随机 [搬运微调]
    前端时间戳处理去年昨天当天基于dayjs
    记录第一次亲自部署.net core 3.0坑
    .net获取/修改配置文件/web.config
    遍历实体类属性获取键值
    Linq以本周和本月为条件的Sql,Liqn查询本周,Linq查询本月
    [基础累积] C#计算时间差
    CSS3自定义滚动条样式方法
    基础的多级菜单一个没见过的思路
  • 原文地址:https://www.cnblogs.com/ddddemo/p/5626731.html
Copyright © 2020-2023  润新知