• Decorator


    Decorator

    动机
    • 在某些情况下我们可能会“过度地使用继承来扩展对象的功能”, 由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性; 并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展 功能的组合)会导致更多子类的膨胀
    • 如何使”对象功能的扩展“能够根据需要动态实现,同时避免”扩展功能的增多“带来的子类膨胀问题,从而使得任何”功能扩展变化“所导致的影响降到最低?
    模式定义

    动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 & 减少子类个数)。

    在这里插入图片描述

    #include 
    
    class Component
    {
    public:
        virtual ~Component() {}
    
        virtual void operation() = 0;
        // ...
    };
    
    class ConcreteComponent : public Component
    {
    public:
        ~ConcreteComponent() {}
    
        void operation()
        {
            std::cout << "Concrete Component operation" << std::endl;
        }
        // ...
    };
    
    class Decorator : public Component // is-a 为了完善接口规范
    {
    private:
        Component *component; // has-a 为了将来具体的实现
    
    public:
        ~Decorator() {}
    
        Decorator(Component *c) : component(c) {}
    
        virtual void operation()
        {
            component->operation();
        }
        // ...
    };
    
    class ConcreteDecoratorA : public Decorator
    {
    public:
        ConcreteDecoratorA(Component *c) : Decorator(c) {}
    
        void operation()
        {
            Decorator::operation();
            std::cout << "Decorator A" << std::endl;
        }
        // ...
    };
    
    class ConcreteDecoratorB : public Decorator
    {
    public:
        ConcreteDecoratorB(Component *c) : Decorator(c) {}
    
        void operation()
        {
            Decorator::operation();
            std::cout << "Decorator B" << std::endl;
        }
        // ...
    };
    
    int main()
    {
        ConcreteComponent *cc = new ConcreteComponent();
        ConcreteDecoratorB *db = new ConcreteDecoratorB(cc);
        ConcreteDecoratorA *da = new ConcreteDecoratorA(db);
    
        Component *component = da;
        component->operation(); 
    
        delete da;
        delete db;
        delete cc;
    
        return 0;
    }
    /*
    Concrete Component operation
    Decorator B
    Decorator A
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    何时场景
    • 动态且透明地向各个对象添加职责,即不影响其他对象
    • 对于可以撤销的责任
    • 当通过子类化扩展不切实际时
    总结
    • 通过采用组合而非继承的手法, Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免 了使用继承带来的“灵活性差”和“多子类衍生问题
    • Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口(为了完善接口规范)。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类(为了将来的具体实现)
    • Decorator模式的目的并非解决“多子类衍生的多继承”问题, Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。
  • 相关阅读:
    旧系统改造
    Unity中Shader的扭曲(不是UV的扭曲)
    港联证券:2万元股票一进一出手续费?
    读《大话数据结构》溢彩加强版
    Tools_Download
    图床项目进度(三)——文件展示页
    基于yolov5的交通标志牌的目标检测研究——源码及文档
    4. Vue入门实战教程之vue-element-admin后端API适配
    代码随想录算法训练营第四十四天| LeetCode518. 零钱兑换 II、LeetCode377. 组合总和 Ⅳ
    计蒜客 T1895切蛋糕(单调队列)
  • 原文地址:https://blog.csdn.net/m0_61386859/article/details/133691407