c++设计模式:装饰者模式(Decorator Pattern)

点点圈 提交于 2020-02-09 00:27:33

定义:

装饰者模式动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

场景:

我们购买咖啡的时候,可以要求在其中加入各种调料,例如:蒸奶、豆浆、摩卡或覆盖奶泡,而咖啡店也会根据所加入的调料收取不同的费用,所以当我们设计订单系统的时候就需要考虑到这些调料部分啦。顾客的需求不一,如果我们针对每种配方都声明一个类得话,系统的维护将会十分头疼。此时装饰者模式就派上用场啦。我们可以根据顾客的需要动态的扩展顾客定制的咖啡,让其加上不同的调料,最终计算出顾客所需缴纳的费用。它的实现有点类似于递归,在实际使用的时候可以慢慢体会。

类图:

c++代码如下:

不使用指针版本:

#include <iostream>#include <string>using namespace std;class Beverage{public:    virtual ~Beverage() {};    virtual string getDescription(); // 必须是虚函数,否则会造成后期使用时描述显示不正确    virtual double cost() = 0;protected:    string m_description;};class CondimentDecorator:public Beverage{public:    virtual string getDescription() = 0;};class Espresso:public Beverage{public:    Espresso();    double cost();};class HouseBlend:public Beverage{public:    HouseBlend();    double cost();};class DarkRoast:public Beverage{public:    DarkRoast();    double cost();};class Decaf:public Beverage{public:    Decaf();    double cost();};class Mocha:public CondimentDecorator{public:    Mocha(Beverage* pBeverage);    string getDescription();    double cost();protected:    Beverage* m_pBeverage;};class Milk:public CondimentDecorator{public:    Milk(Beverage* pBeverage);    string getDescription();    double cost();protected:    Beverage* m_pBeverage;};class Soy:public CondimentDecorator{public:    Soy(Beverage* pBeverage);    string getDescription();    double cost();protected:    Beverage* m_pBeverage;};class Whip:public CondimentDecorator{public:    Whip(Beverage* pBeverage);    string getDescription();    double cost();protected:    Beverage* m_pBeverage;};string Beverage::getDescription(){    return m_description;}Espresso::Espresso(){    m_description = "Espresso";}double Espresso::cost(){    return 1.99;}HouseBlend::HouseBlend(){    m_description = "House Blend Coffee";}double HouseBlend::cost(){    return 0.89;}DarkRoast::DarkRoast(){    m_description = "Dark Roast Coffee";}double DarkRoast::cost(){    return 0.99;}Decaf::Decaf(){    m_description = "Decaf Coffee";}double Decaf::cost(){    return 1.05;}Mocha::Mocha(Beverage* pBeverage){    m_pBeverage = pBeverage;}string Mocha::getDescription(){    return m_pBeverage->getDescription() + " + Mocha";}double Mocha::cost(){    return 0.20 + m_pBeverage->cost();}Milk::Milk(Beverage* pBeverage){    m_pBeverage = pBeverage;}string Milk::getDescription(){    return m_pBeverage->getDescription() + " + Milk";}double Milk::cost(){    return 0.10 + m_pBeverage->cost();}Soy::Soy(Beverage* pBeverage){    m_pBeverage = pBeverage;}string Soy::getDescription(){    return m_pBeverage->getDescription() + " + Soy";}double Soy::cost(){    return 0.15 + m_pBeverage->cost();}Whip::Whip(Beverage* pBeverage){    m_pBeverage = pBeverage;}string Whip::getDescription(){    return m_pBeverage->getDescription() + " + Whip";}double Whip::cost(){    return 0.10 + m_pBeverage->cost();}int main(){    Espresso espresso;    cout << espresso.getDescription() << " $" << espresso.cost() << endl;    DarkRoast darkRoast;    Mocha mocha1(&darkRoast);    Mocha mocha2(&mocha1);    Whip whip1(&mocha2);    cout << whip1.getDescription() << " $" << whip1.cost() << endl;    HouseBlend houseBlend;    Soy soy1(&houseBlend);    Mocha mocha3(&soy1);    Whip whip2(&mocha3);    cout << whip2.getDescription() << " $" << whip2.cost() << endl;    return 0;}

 

使用指针版本:

 

#include <iostream>#include <string>using namespace std;class Beverage{public:    virtual ~Beverage() {};    virtual string getDescription();    virtual double cost() = 0;protected:    string m_description;};class CondimentDecorator:public Beverage{public:    virtual string getDescription() = 0;};class Espresso:public Beverage{public:    Espresso();    double cost();};class HouseBlend:public Beverage{public:    HouseBlend();    double cost();};class DarkRoast:public Beverage{public:    DarkRoast();    double cost();};class Decaf:public Beverage{public:    Decaf();    double cost();};class Mocha:public CondimentDecorator{public:    Mocha(Beverage* pBeverage);    ~Mocha();    string getDescription();    double cost();protected:    Beverage* m_pBeverage;};class Milk:public CondimentDecorator{public:    Milk(Beverage* pBeverage);    ~Milk();    string getDescription();    double cost();protected:    Beverage* m_pBeverage;};class Soy:public CondimentDecorator{public:    Soy(Beverage* pBeverage);    ~Soy();    string getDescription();    double cost();protected:    Beverage* m_pBeverage;};class Whip:public CondimentDecorator{public:    Whip(Beverage* pBeverage);    ~Whip();    string getDescription();    double cost();protected:    Beverage* m_pBeverage;};string Beverage::getDescription(){    return m_description;}Espresso::Espresso(){    m_description = "Espresso";}double Espresso::cost(){    return 1.99;}HouseBlend::HouseBlend(){    m_description = "House Blend Coffee";}double HouseBlend::cost(){    return 0.89;}DarkRoast::DarkRoast(){    m_description = "Dark Roast Coffee";}double DarkRoast::cost(){    return 0.99;}Decaf::Decaf(){    m_description = "Decaf Coffee";}double Decaf::cost(){    return 1.05;}Mocha::Mocha(Beverage* pBeverage){    m_pBeverage = pBeverage;}Mocha::~Mocha(){    delete m_pBeverage;}string Mocha::getDescription(){    return m_pBeverage->getDescription() + " + Mocha";}double Mocha::cost(){    return 0.20 + m_pBeverage->cost();}Milk::Milk(Beverage* pBeverage){    m_pBeverage = pBeverage;}Milk::~Milk(){    delete m_pBeverage;}string Milk::getDescription(){    return m_pBeverage->getDescription() + " + Milk";}double Milk::cost(){    return 0.10 + m_pBeverage->cost();}Soy::Soy(Beverage* pBeverage){    m_pBeverage = pBeverage;}Soy::~Soy(){    delete m_pBeverage;}string Soy::getDescription(){    return m_pBeverage->getDescription() + " + Soy";}double Soy::cost(){    return 0.15 + m_pBeverage->cost();}Whip::Whip(Beverage* pBeverage){    m_pBeverage = pBeverage;}Whip::~Whip(){    delete m_pBeverage;}string Whip::getDescription(){    return m_pBeverage->getDescription() + " + Whip";}double Whip::cost(){    return 0.10 + m_pBeverage->cost();}int main(){    Beverage* pBeverage = new Espresso();    cout << pBeverage->getDescription() << " $" << pBeverage->cost() << endl;    Beverage* pBeverage2 = new DarkRoast();    pBeverage2 = new Mocha(pBeverage2);    pBeverage2 = new Mocha(pBeverage2);    pBeverage2 = new Whip(pBeverage2);    cout << pBeverage2->getDescription() << " $" << pBeverage2->cost() << endl;    Beverage* pBeverage3 = new HouseBlend();    pBeverage3 = new Soy(pBeverage3);    pBeverage3 = new Mocha(pBeverage3);    pBeverage3 = new Whip(pBeverage3);    cout << pBeverage3->getDescription() << " $" << pBeverage3->cost() << endl;    delete pBeverage;    delete pBeverage2;    delete pBeverage3;    return 0;}




运行后结果如下:

Espresso $1.99
Dark Roast Coffee + Mocha + Mocha + Whip $1.49
House Blend Coffee + Soy + Mocha + Whip $1.34

 

参考图书:《Head First 设计模式》

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!