设计模式之装饰器模式

装饰器模式(Decorator Pattern)

定义

装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象添加功能。在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

 

常用场景

1.以动态透明的方式给单个对象添加职责;
2.不采用子类的方式进行扩充。

 

优点

装饰类和被装饰类可以独立发展,不会互相耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

 

缺点

多层装饰比较复杂

 

C++实现

例子:

举例:制作饮料

饮料店有很多种饮料(咖啡、果汁等),在原有饮料基础上,不同的顾客会要求添加不同的配料(冰块、糖等)。此时,在不允许继承的情况下,可以将基础咖啡内嵌到另一个类中,由另一个类完成这些操作,而不破坏原有的具体饮料类,称这个嵌入的类为装饰。

类图:

                                

代码:

#include <iostream>
#include <string>

using std::cout;
using std::endl;

class Drink  
{
public:

    Drink() : m_description("") {}

    virtual ~Drink() {}

    virtual void AddDescription(std::string str)  // 添加描述
    {
        m_description += str;
    }

    void ShowDescription() // 获取描述
    {
        std::cout<< m_description <<std::endl;
    }  

private:
    std::string m_description;  // 对饮料的描述
};

// 具体饮料类
// 果汁
class Juice : public Drink 
{
public:
    Juice() : Drink()
    {
        AddDescription("果汁");
    }
};

// 咖啡
class Cofffee : public Drink 
{
public:
    Cofffee() : Drink()
    {
        AddDescription("咖啡");
    }
};

// 装饰器类
class Decorator
{
public:
    Decorator(Drink* drink) : m_drink(drink) {}
    virtual ~Decorator() {}

    Drink* GetDrink() {return m_drink;}

    virtual void AddDecorate() = 0; // 添加装饰

private:
    Drink* m_drink; // 内嵌饮料引用, 外部释放
};

// 添加冰块
class Ice : public Decorator
{
public:
    Ice(Drink* drink) : Decorator(drink), m_decorate(", 添加冰块")
    {
    }

    void AddDecorate() 
    {
        GetDrink()->AddDescription(m_decorate);
    }

private:
    std::string m_decorate;
};

// 添加糖
class Sugar : public Decorator
{
public:
    Sugar(Drink* drink) : Decorator(drink), m_decorate(", 添加糖") {}

    void AddDecorate() 
    {
        GetDrink()->AddDescription(m_decorate);
    }

private:
    std::string m_decorate;
};

int main(int argc, char** argv)
{
    Drink* pJuice = new Juice();
    Ice* pDecoJuice = new Ice(pJuice);
    pDecoJuice->AddDecorate();
    pJuice->ShowDescription();

    Drink* pCoffee = new Cofffee();
    Sugar* pDecoCoffee1 = new Sugar(pCoffee);
    pDecoCoffee1->AddDecorate();
    Ice* pDecoCoffee2 = new Ice(pCoffee);
    pDecoCoffee2->AddDecorate();
    pCoffee->ShowDescription();

    delete pDecoCoffee2;
    delete pDecoCoffee1;
    delete pCoffee;
    delete pDecoJuice;
    delete pJuice;

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值