• C++之装饰模式


    装饰器模式(Decorator Pattern):允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

    装饰者模式适用场景:

    1)以动态的方式给对象添加职责。

    2)处理那些可以撤销的职责。

    3)当采用生成子类的方法进行扩充时,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。

     

    (1)抽象组件(Component):给出一个抽象接口,以规范准备接受附加责任的对象。

    (2)被装饰者(ConcreteComponent):Component的具体实现,也就是我们要装饰的具体对象。

    (3)装饰者组件(Decorator):持有组件对象的实例引用,该类的职责就是为了装饰具体组件对象,定义的基类。

    (4)具体装饰(ConcreteDecorator):负责给构件对象装饰附加的功能。

     

    装饰者模式实现步骤:
    1.增强类与被增强类实现同一接口
    2.增强类里面得到被增强类的引用(只要在增强类里面传入被增强类对象的一定就是装饰者模式)
    3.对于不需要改写的方法,调用被增强类原有方法,对应需要改写增强的方法写自己的逻辑

    下面就以一杯奶茶说起,我最喜欢喝大杯阿水茶的珍珠奶茶,可是有时候也会不满足奶茶只有珍珠,在天气热的时候我还要加冰块,心情好的时候再加个椰果等,这些其实都是对奶茶的拓展即装饰。

    我们来创建一个奶茶的抽象类,相当于Component

    class Milk_Tea

    {

    public:

    virtual void request(){};

    };

    再写一个珍珠奶茶类,相当于被装饰者

    class Milk_Tea

    {

    public:

    virtual void request(){};

    };

    然后实现装饰类:

    class Decorator:public Milk_Tea {

    protected:

    Milk_Tea *milkyTea;

    public:

    Decorator(Milk_Tea *a){

    milkyTea=a;

    }

    virtual void request(){

    milkyTea->request();

    }

    };

    分别写出不同装饰具体类:

    class Add1:public Decorator {

    public:

    Add1(Milk_Tea *a):Decorator(a){

    }

    void request() {

    milkyTea->request();

    add_ice();

    }

    void add_ice(){

    cout<<"天好热啊,老板我想加个冰。。。"<<endl;

    }

    };

    class Add2:public Decorator {

    public:

    Add2(Milk_Tea *a):Decorator(a){

    }

    void request(){

    milkyTea->request();

    add_fruit();

    }

    void add_fruit(){

    cout<<"再加个椰果,谢谢。。。"<<endl;

    }

    };

    客户端:

    int main()

    {

    Milk_Tea *m1=new Bubble_Tea();

    Decorator *m2=new Add1(m1);

    Decorator *m3=new Add2(m2);

    m3->request();

    return 0;

    }

    效果:

    优点

    1、目的在于扩展对象的功能。装饰者模式提供比继承更好的灵活性。装饰是动态的,运行时可以修改的;继承是静态的,编译期便已确定好。

    2、通过使用不同的装饰类及对他们的排列组合,可以创造出许多不同行为的组合。

    缺点

    1 产生很多的小对象,大量的小对象会占用内存。

    2 组合方式很多,很容易出错。

     

     

     

  • 相关阅读:
    [BZOJ1004] [HNOI2008]Cards解题报告(Burnside引理)
    [POJ1286&POJ2154&POJ2409]Polya定理
    monkey工具介绍及用法
    adb 命令使用与解释
    android-sdk的安装及配置
    spring-boot 加入拦截器Interceptor
    对spring boot 之AutoConfiguration 的理解
    java 集合操作小结
    java -d . **.java 与 java **.java 的区别
    关于Eclipse SVN 分支 与主干 小结
  • 原文地址:https://www.cnblogs.com/xiaxiaopi/p/12743978.html
Copyright © 2020-2023  润新知