设计模式之装饰模式

⭐   装饰者模式动态地将责任附加到对象上。

  • 若要扩展功能,装饰者模式提供了比继承更有弹性的替代方案。
  • 适用场景:需要动态的给现有对象添加功能,并且能够实现不同功能的组合。

 

举2个例子来理解:

咖啡,不同的咖啡加不同的配料,例如玛奇朵+双倍焦糖+奶盖,摩卡+奶盖

游戏角色,不同的游戏人物服装、使用武器不同,战士+盔甲+刀剑,法师+长袍+法杖

如果通过单纯的类继承来实现的话,将会有咖啡类、玛奇朵+双倍焦糖+奶盖的咖啡类、摩卡+奶盖的咖啡类。未来再有别的搭配的话,又要实现一个新的咖啡类,将会带来数量庞大的一堆子类,不易组合且代码量大。

装饰模式的实现

1、需要有被修饰的对象基类A、被修饰的对象派生类A-Child

2、被修饰的对象的一个方法A-Func

3、装饰基类D,从被修饰的对象基类A派生,缓存一个被修饰的对象基类对象(A *a),添加扩展方法D-Func,实现2中的方法并在其中调用D-Func

4、从装饰基类派生各种装饰类D-Child

5、使用时先生成一个被装饰对象A-Child,指向基类指针A*,然后你想给他添加什么扩展功能,就再实例化一个D-Child传入A*即可

代码如下

class Coffee

{

public:

    Coffee()

    {

        //std::cout << "Coffee construction!" << endl;

    }

    virtual ~Coffee()

    {

        //std::cout << "Coffee destruction!" << endl;

    }

 

    virtual void showme() = 0;

};

 

class CMachiatto :public Coffee

{

public:

    CMachiatto()

    {

        //std::cout << "Machiatto construction!" << endl;

    }

    ~CMachiatto()

    {

        //std::cout << "Machiatto destruction!" << endl;

    }

    void showme()

    {

        std::cout << "This is Machiatto!" << endl;

    }

};

 

class CMocha :public Coffee

{

public:

    CMocha()

    {

        //std::cout << "Macho construction!" << endl;

    }

    ~CMocha()

    {

        //std::cout << "Macho destruction!" << endl;

    }

    void showme()

    {

        std::cout << "This is Macho!" << endl;

    }

};

 

 

class Decorate :public Coffee

{

public:

    Decorate(Coffee *i_ptrCoffee)

    {

        //std::cout << "Decorate construction!" << endl;

        m_coffee = i_ptrCoffee;

    }

    ~Decorate()

    {

        //std::cout << "Decorate destruction!" << endl;

        delete m_coffee;

        m_coffee = NULL;

    }

 

    void showme()

    {

        m_coffee->showme();

        showdecorate();

    }

    virtual void showdecorate() = 0;

private:

    Coffee *m_coffee;

 

};

 

 

class CCaramel :public Decorate

{

public:

    CCaramel(Coffee *i_ptrCoffee) : Decorate(i_ptrCoffee)

    {

        //std::cout << "Caramel construction!" << endl;

    }

    ~CCaramel()

    {

        //std::cout << "Caramel destruction!" << endl;

    }

 

    void showdecorate()

    {

        std::cout << "Add some caramel!" << endl;

    }

};

 

class CMilk :public Decorate

{

public:

    CMilk(Coffee *i_ptrCoffee): Decorate(i_ptrCoffee)

    {

        //std::cout << "Milk construction!" << endl;

    }

    ~CMilk()

    {

        //std::cout << "Milk destruction!" << endl;

    }

 

    void showdecorate()

    {

        std::cout << "Add some milk!" << endl;

    }

};

 

int main()

{

    //双焦糖+奶盖

    Coffee *coff = new CMachiatto;

    coff = new CCaramel(coff);

    coff = new CCaramel(coff);

    coff = new CMilk(coff);

    coff->showme();

 

    delete coff;

    coff = NULL;

 

 

    //摩卡+奶盖

    Coffee *newcoff = new CMocha;

    newcoff = new CMilk(newcoff);

    newcoff->showme();

 

    delete newcoff;

    newcoff = NULL;

 

    return 0;

}

运行结果如下:

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值