C++ 设计模式之装饰者模式

49 阅读1分钟
//以奶茶店为例子

#define _CRTDBG_MAP_ALLOC
#ifdef _DEBUG
#define MYDEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__)
#define new MYDEBUG_NEW
#else
#define MYDEBUG_NEW
#endif

#include <iostream>
#include <string>
#include <stdlib.h>
#include <crtdbg.h>

using namespace std;

//奶茶类,抽象类
class MilkTea {
public:
	string description = "未知奶茶";

	virtual std::string getDescription() {
		return description;
	}

	virtual double cost() = 0;

	virtual void deleter() = 0;
};

class CondimentDecorator : public MilkTea {

public:
	MilkTea* milkTea;

	void deleter() {
		if (milkTea)
			milkTea->deleter();
		delete this;
	}
};

//实现奶茶类
class BobaMilkTea : public MilkTea {
public:
	BobaMilkTea() {
		description = "波霸奶茶";
	}

	double cost() {
		return 5.0;
	}

	void deleter() {
		delete this;
	}
};

//实现配料类

//糖
class Sugar : public CondimentDecorator {
public:
	Sugar(MilkTea* mt) {
		description = "糖";
		milkTea = mt;
	}

	double cost() {
		return 1.0 + milkTea->cost();
	}

	std::string getDescription() {
		return milkTea->getDescription() + ", " + description;
	}
};

//布丁
class Pudding : public CondimentDecorator {
public:
	Pudding(MilkTea* mt) {
		description = "布丁";
		milkTea = mt;
	}

	double cost() {
		return 1.3 + milkTea->cost();
	}

 	std::string getDescription() {
		return milkTea->getDescription() + ", 布丁";
	}
};


int main ()
{
	//单点奶茶不加糖
	MilkTea* mt1 = new BobaMilkTea();
	cout << mt1->getDescription() << ": $" << mt1->cost() << endl;
	mt1->deleter();

	//波霸奶茶加两份糖
	MilkTea* mt2 = new BobaMilkTea();
	mt2 = new Sugar(mt2);
	mt2 = new Sugar(mt2);

	cout << mt2->getDescription() << ": $" << mt2->cost() << endl;
	mt2->deleter();

	//波霸奶茶加布丁
	MilkTea* mt3 = new BobaMilkTea();
	mt3 = new Pudding(mt3);

	cout << mt3->getDescription() << ": $" << mt3->cost() << endl;
	mt3->deleter();

	_CrtDumpMemoryLeaks();

	return 0;
}