装饰器模式
作用:
装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象添加功能。在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。装饰器模式有点类似于建造者模式,两者的区别是建造者模式必须按照统一的步骤来构建某个对象,而装饰器模式不需要。
示例:
题目是这样的:某咖啡店当卖咖啡时,可以根据顾客的要求在其中加入各种配料,咖啡店会根据所加入的配料来计算费用。咖啡店所供应的咖啡及配料的种类和价格如下表所示。
咖啡有两种:
- 蒸馏咖啡Espresso 25元/杯;
- 深度烘焙咖啡DarkRoast 20元/杯;
可以在咖啡里面加配料:
- 摩卡Mocha 10元/份;
- 奶泡Whip 8元/份;
现采用装饰器模式Decorator模式来实现计算费用的功能,得到如图5-1所示的类图。
// Cplus_study.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
//定义各商品的价格
const int ESPRESSO_PRICE = 25;
const int DRAKROAST_PRICE = 20;
const int MOCHA_PRICE = 10;
const int WHIP_PRICE = 8;
class Beverage {//饮料
protected:
string description;
public:
virtual string getDescription() { //这里virtual不能省,不然找不到上一级的Beverage的了
return description;
}
virtual int cost()=0;
};
class CondimentDecorator : public Beverage {//配料
protected:
Beverage *beverage;//这个指针,用于回溯之前已经存在的内容
};
//两种咖啡,其构造函数皆没有Beverage *beverage;也就是说,这两个类只能作为基础,不能作为叠加上去的配件。
class Espresso : public Beverage{//蒸馏咖啡
public:
Espresso(){
description="Espresso";
}
int cost(){
return ESPRESSO_PRICE;
}
};
class DarkRoast : public Beverage {//深度烘焙咖啡
public:
DarkRoast(){
description = "DardRoast";
}
int cost(){
return DRAKROAST_PRICE;
}
};
//对比起上述两种“基类”,这两种东西构造函数皆存在Beverage *beverage;
//(Beverage *beverage;的声明源于对CondimentDecorator这个类的继承),其可以叠加
class Mocha : public CondimentDecorator {//摩卡
public:
Mocha(Beverage* beverage){
this->beverage=beverage;
}
string getDescription(){
return beverage->getDescription()+",Mocha";
}
int cost(){
return MOCHA_PRICE+beverage->cost();
}
};
class Whip :public CondimentDecorator {//奶泡
public:
Whip(Beverage* beverage){
this->beverage=beverage;
}
string getDescription() {
return beverage->getDescription()+",Whip";
}
int cost() {
return WHIP_PRICE+beverage->cost();
}
};
int main(){
Beverage* beverage = new DarkRoast();
beverage = new Mocha(beverage);
beverage = new Whip(beverage);
cout << beverage->getDescription().c_str() << "¥" << beverage->cost() << endl;
system("pause");
return 0;
}
结果:
参考