《Head First 设计模式》例子的C++实现(3 装饰模式)

《Head First 设计模式》例子的C++实现(3 装饰模式)

装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
装饰模式的特点是 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互。
但是这种模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

下面是代码:


///Beverage.h

#ifndef BEVERAGE_H
#define BEVERAGE_H
#include <QString>

class Beverage
{
public:
    Beverage():description("Unknown Beverage") {}
    virtual QString getDescription() {return description;}
    virtual double cost() = 0;
protected:
    QString description;
};

#endif // BEVERAGE_H
///CondimentDecorator.h
#ifndef CONDIMENTDECORATOR_H
#define CONDIMENTDECORATOR_H

#include "beverage.h"

class CondimentDecorator : public Beverage
{
public:
    CondimentDecorator(){}
};

#endif // CONDIMENTDECORATOR_H
///DarkRoast.h
#ifndef DARKROAST_H
#define DARKROAST_H

#include "beverage.h"

class DarkRoast : public Beverage
{
public:
    DarkRoast() {description = "Dark Roast Coffee";}
    double cost() override {return 0.99;}
};

#endif // DARKROAST_H
///Decaf.h
#ifndef DECAF_H
#define DECAF_H

#include "beverage.h"

class Decaf : public Beverage
{
public:
    Decaf(){description = "Decaf Coffee";}
    double cost() override {return 1.;}
};

#endif // DECAF_H
///Espresso.h
#ifndef ESPRESSO_H
#define ESPRESSO_H

#include "beverage.h"

class Espresso : public Beverage
{
public:
    Espresso() {description = "Espresso";}
    double cost() override {return 1.99;}
};

#endif // ESPRESSO_H
///HouseBlend.h
#ifndef HOUSEBLEND_H
#define HOUSEBLEND_H

#include "beverage.h"

class HouseBlend : public Beverage
{
public:
    HouseBlend(){description = "House Blend Coffee";}
    double cost() override {return 0.89;}
};

#endif // HOUSEBLEND_H
///Milk.h
#ifndef MILK_H
#define MILK_H

#include "condimentdecorator.h"

class Milk : public CondimentDecorator
{
public:
    Milk(Beverage *beverage);
    QString getDescription();
    double cost() override;
private:
    Beverage *m_beverage;
};

#endif // MILK_H
#include "milk.h"

Milk::Milk(Beverage *beverage)
{
    m_beverage = beverage;
//    description = m_beverage->getDescription() + ", Milk";
}

QString Milk::getDescription()
{
    return m_beverage->getDescription() + ", Milk";
}

double Milk::cost()
{
    return 0.10 + m_beverage->cost();
}
///Mocha.h
#ifndef MOCHA_H
#define MOCHA_H

#include "condimentdecorator.h"

class Mocha : public CondimentDecorator
{
public:
    Mocha(Beverage *beverage);
    QString getDescription();
    double cost() override;
private:
    Beverage *m_beverage;
};

#endif // MOCHA_H
#include "mocha.h"

Mocha::Mocha(Beverage *beverage)
{
    m_beverage = beverage;
//    description = m_beverage->getDescription() + ", Mocha";
}

QString Mocha::getDescription()
{
    return m_beverage->getDescription() + ", Mocha";
}

double Mocha::cost()
{
    return 0.20 + m_beverage->cost();
}
///Soy.h
#ifndef SOY_H
#define SOY_H

#include "condimentdecorator.h"

class Soy : public CondimentDecorator
{
public:
    Soy(Beverage *beverage);
    QString getDescription();
    double cost() override;
private:
    Beverage *m_beverage;
};

#endif // SOY_H
#include "soy.h"

Soy::Soy(Beverage *beverage)
{
    m_beverage = beverage;
//    description = m_beverage->getDescription() + ", Soy";
}

QString Soy::getDescription()
{
    return m_beverage->getDescription() + ", Soy";
}

double Soy::cost()
{
    return 0.15 + m_beverage->cost();
}
///Whip.h
#ifndef WHIP_H
#define WHIP_H

#include "condimentdecorator.h"

class Whip : public CondimentDecorator
{
public:
    Whip(Beverage *beverage);
    QString getDescription();
    double cost() override;
private:
    Beverage *m_beverage;
};

#endif // WHIP_H
#include "whip.h"

Whip::Whip(Beverage *beverage)
{
    m_beverage = beverage;
//    description = m_beverage->getDescription() + ", Whip";
}

QString Whip::getDescription()
{
    return m_beverage->getDescription() + ", Whip";
}

double Whip::cost()
{
    return 0.10 + m_beverage->cost();
}
#include <QCoreApplication>
#include <QDebug>
#include "espresso.h"
#include "darkroast.h"
#include "houseblend.h"
#include "milk.h"
#include "mocha.h"
#include "soy.h"
#include "whip.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Beverage *beverage = new Espresso();
    qDebug() << beverage->getDescription() << " $"  << beverage->cost();


    Beverage *beverage2 = new DarkRoast();
    beverage2 = new Mocha(beverage2);
    beverage2 = new Mocha(beverage2);
    beverage2 = new Whip(beverage2);
    qDebug() <<beverage2->getDescription() << " $" << beverage2->cost();

    Beverage *beverage3 = new HouseBlend();
    beverage3 = new Soy(beverage3);
    beverage3 = new Mocha(beverage3);
    beverage3 = new Whip(beverage3);
    qDebug() << beverage3->getDescription() << " $"  << beverage3->cost();

    return a.exec();
}

这个小例子就能将装饰模式的优缺点都体现出来了。用了装饰模式 main 函数的代码非常的简洁。但是代价是多出来了将近10个小类。

我个人不推荐使用这种设计模式。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值