C++装饰者模式:Decorator Pattern

设计原则:类应该对扩展开发,对修改关闭。

装饰者可以在所委托被装饰者的行为之后加上自己的行为,以达到特定的目的。

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

装饰者和被装饰者必须是一样的类型,也就是有相同的超类,因为装饰者新的行为必须能取代被装饰者。

假设在一家咖啡饮料店中,有饮料Decaf(低咖)、Tea(茶) 和可以添加的调料比如milk、mocha、sugar等,不同的用户可能会购买不同组合的饮料,并且在后续的营业中可能会出现新的饮料或者调料,现需要计算不同饮料的最终价格。

类图:

 要让调料类可以引用到饮料类,做法:把饮料作为调料的构造器的参数,将饮料保存到调料的成员变量中。

 注:1.其他饮料类和调料类的实现相同,所以项目内只实现了饮料Tea类和调料Milk类;

        2.装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂;

实现如下:

beverage.h:

#ifndef BEVERAGE_H
#define BEVERAGE_H
#include <iostream>
#include <string>
using namespace std;

class Beverage {
public:
    virtual string getDescription() = 0;
    virtual double cost() = 0;

protected: // 只传给子类
    string m_description;
};


#endif // BEVERAGE_H

tea.h:

#ifndef TEA_H
#define TEA_H
#include "beverage.h"

class Tea : public Beverage {
public:
    Tea();
    virtual string getDescription() override;
    virtual double cost() override;

};

Tea::Tea()
{
    m_description = "茶";
}

string Tea::getDescription()
{
    return m_description;
}

double Tea::cost()
{
    return 7.0;
}
#endif // TEA_H

condimentDecorator.h:

#ifndef CONDIMENTDECORATOR_H
#define CONDIMENTDECORATOR_H
#include "beverage.h"

class CondimentDecorator : public Beverage {
public:
    virtual string getDescription() = 0;
};

#endif // CONDIMENTDECORATOR_H

milk.h:

#ifndef MILK_H
#define MILK_H
#include "condimentDecorator.h"


class Milk : public CondimentDecorator {
public:
    Milk(Beverage* beverage);
    virtual string getDescription() override;
    virtual double cost() override;

private:
    Beverage* m_beverage;

};

Milk::Milk(Beverage *beverage)
{
    m_beverage = beverage;
}

string Milk::getDescription()
{
    return m_beverage->getDescription() + " + 牛奶";
}

double Milk::cost()
{
    return m_beverage->cost() + 2.0;
}

#endif // MILK_H

main.cpp:

/*
 * 装饰者模式
 *
 * date:2023-9-7
*/

// milk: 2.0
// tea: 7.0

#include "tea.h"
#include "milk.h"

int main()
{

    cout << "要一杯茶,加一份牛奶" << endl;
    Beverage* beverage1 = new Tea();

    Beverage* beverage2 = new Milk(beverage1);

    cout << "订阅信息:" << beverage2->getDescription() <<
            " ,花费金额:" << beverage2->cost() << endl << endl;


    cout << "要一杯茶,加两份牛奶" << endl;
    Beverage* beverage3 = new Tea();
    Beverage* beverage4 = new Milk(beverage3);
    Beverage* beverage5 = new Milk(beverage4);

    cout << "订阅信息:" << beverage5->getDescription() <<
            " ,花费金额:" << beverage5->cost() << endl;


}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值