zoukankan      html  css  js  c++  java
  • 深入 Laravel 内核之装饰模式

    装饰模式核心内容:

    • 装饰模式可以在不影响组件对象的情况下,以动态、透明的方式从外部给对象添加功能;
    • 装饰器模式的本质就是动态组合。动态是手段,组合是目的。装饰模式是通过把复杂的功能简单化、分散化,在运行期间,根据需要来动态组合出需要的功能;
    • 使用不同的装饰类以及这些装饰类的排列组合,可以创造出很多不同功能的对象。可以使用多个装饰类来装饰同一对象,创造功能更为强大的对象;
    • 装饰抽象类的接口必须与组件抽象类的接口相同,对于客户端来说无论是装饰之前的对象还是装饰之后的对象都可以使用同样的方式调用;
    • 组件实现类 ConcreteComponent 应该尽量保持简洁和轻量,不要把主逻辑之外的辅助逻辑和状态放在组件实现类中,应该通过装饰类对其进行扩展。

    定义一个组件抽象类:

    abstract class Component
    {
        abstract public function operation();
    }
    

    定义一个组件实现类,实现组件功能:

    class ConcreteComponent extends Component
    {
        public function operation()
        {
            echo __CLASS__ .  '|' . __METHOD__ . "
    ";
        }
    }
    
    

    定义一个装饰器抽象类,接口与组件类一致:

    abstract class Decorator extends Component
    {
        /**
         * 持有Component对象,该对象就是被装饰的对象
         */
        protected $component;
    
        /**
         * 构造方法传入
         * @param Component $component
         */
        public function __construct(Component $component)
        {
            $this->component = $component;
        }
    
        abstract public function operation();
    }
    

    定义两个装饰器,用来扩展原有组件的功能,或者实现新的功能:

    class ConcreteDecoratorA extends Decorator
    {
        public function beforeOperation()
        {
            echo __CLASS__ . '|' . __METHOD__ . "
    ";
        }
    
        public function afterOperation()
        {
            echo __CLASS__ . '|' . __METHOD__ . "
    ";
        }
    
        public function operation()
        {
            $this->beforeOperation();
            //这里可以调用父类的方法,也可以不调用直接改写实现新功能
            $this->component->operation();
            $this->afterOperation();
        }
    }
    
    class ConcreteDecoratorB extends Decorator
    {
        public function beforeOperation()
        {
            echo __CLASS__ . '|' . __METHOD__ . "
    ";
        }
    
        public function afterOperation()
        {
            echo __CLASS__ . '|' . __METHOD__ . "
    ";
        }
    
        public function operation()
        {
            $this->beforeOperation();
            //这里可以调用父类的方法,也可以不调用直接改写实现新功能
            $this->component->operation();
            $this->afterOperation();
        }
    }
    

    客户端使用示例:

    class Client
    {
        public function main()
        {
            $component = new ConcreteComponent();
            echo "
    直接使用组件:
    ";
            $component->operation();
            
            $decoratorA = new ConcreteDecoratorA($component);
            echo "
    使用装饰器A装饰后的组件:
    ";
            $decoratorA->operation();
            
            $decoratorB = new ConcreteDecoratorB($decoratorA);
            echo "
    使用装饰器A和B装饰后的组件:
    ";
            $decoratorB->operation();
        }
    }
    
    $client = new Client();
    $client->main();
    
  • 相关阅读:
    HDU 1335 Basically Speaking(进制转换)
    2016年团体程序设计天梯赛-决赛 L2-3. 互评成绩(25)
    2016年团体程序设计天梯赛-决赛 L1-8. Left-pad(20)
    2016年团体程序设计天梯赛-决赛 L1-7. 到底是不是太胖了(10)
    2016年团体程序设计天梯赛-决赛 L1-6. 一帮一(15)
    2016年团体程序设计天梯赛-决赛 L1-5. 是不是太胖了(5)
    2016年团体程序设计天梯赛-决赛 L1-3. 出租(20)
    2016年团体程序设计天梯赛-决赛 L1-2. I Love GPLT(5)
    2016年团体程序设计天梯赛-决赛 L1-1. 正整数A+B(15)
    Codeforces Round #321 (Div. 2) C. Kefa and Park dfs
  • 原文地址:https://www.cnblogs.com/danhuang/p/13176699.html
Copyright © 2011-2022 走看看