c++设计模式:装饰者模式(Decorator Pattern)
2013-04-06 19:12
615 查看
定义:
装饰者模式动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
场景:
我们购买咖啡的时候,可以要求在其中加入各种调料,例如:蒸奶、豆浆、摩卡或覆盖奶泡,而咖啡店也会根据所加入的调料收取不同的费用,所以当我们设计订单系统的时候就需要考虑到这些调料部分啦。顾客的需求不一,如果我们针对每种配方都声明一个类得话,系统的维护将会十分头疼。此时装饰者模式就派上用场啦。我们可以根据顾客的需要动态的扩展顾客定制的咖啡,让其加上不同的调料,最终计算出顾客所需缴纳的费用。它的实现有点类似于递归,在实际使用的时候可以慢慢体会。
类图:
c++代码如下:
不使用指针版本:
使用指针版本:
运行后结果如下:
Espresso $1.99
Dark Roast Coffee + Mocha + Mocha + Whip $1.49
House Blend Coffee + Soy + Mocha + Whip $1.34
参考图书:《Head First 设计模式》
装饰者模式动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
场景:
我们购买咖啡的时候,可以要求在其中加入各种调料,例如:蒸奶、豆浆、摩卡或覆盖奶泡,而咖啡店也会根据所加入的调料收取不同的费用,所以当我们设计订单系统的时候就需要考虑到这些调料部分啦。顾客的需求不一,如果我们针对每种配方都声明一个类得话,系统的维护将会十分头疼。此时装饰者模式就派上用场啦。我们可以根据顾客的需要动态的扩展顾客定制的咖啡,让其加上不同的调料,最终计算出顾客所需缴纳的费用。它的实现有点类似于递归,在实际使用的时候可以慢慢体会。
类图:
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 设计模式》
相关文章推荐
- 我所理解的设计模式(C++实现)——装饰者模式(Decorator Pattern)
- c++设计模式:装饰者模式(Decorator Pattern)
- 我所理解的设计模式(C++实现)——装饰者模式(Decorator Pattern)
- 我所理解的设计模式(C++实现)——装饰者模式(Decorator Pattern)
- 我所理解的设计模式(C++实现)——装饰者模式(Decorator Pattern)
- Head First 设计模式 (三) 装饰者模式(decorator pattern) C++实现
- Head First 设计模式——装饰者模式(Decorator Pattern)
- Android设计模式之装饰者模式(Decorator Pattern)
- Android设计模式之中的一个个样例让你彻底明确装饰者模式(Decorator Pattern)
- 设计模式-装饰者模式(Decorator Pattern)
- 设计模式笔记3:装饰者模式(Decorator Pattern)
- (C++)设计模式------装饰者模式 decorator
- 设计模式 - 装饰者模式(Decorator Pattern) Java的IO类 使用方法
- 设计模式学习--装饰者模式(Decorator Pattern)
- C#设计模式——装饰者模式(Decorator Pattern)
- 设计模式之装饰者模式Decorator Pattern
- Java设计模式之装饰者模式(Decorator pattern)
- 设计模式(九)装饰者模式(Decorator Pattern)
- 设计模式学习笔记--装饰者模式(Decorator Pattern)
- Net设计模式实例之装饰者模式(Decorator Pattern)