装饰者模式:
能够动态地往一个类中添加新的行为。相比继承是在编译时添加行为,装饰模式是在运行时添加行为。
星巴克咖啡是讲述装饰者模式的一个很好的例子。
假设现在有两种咖啡:HouseBlend、DarkRoast,同时有两种调料:Milk、Mocha。那么此时我们可以给顾客提供以下咖啡:
HouseBlend、HouseBlendWithMilk、HouseBlendWithMocha、HouseBlendWithMilkandMocha、
DarkRoast、DarkRoastWithMilk、DarkRoastWithMocha、DarkRoastWithMilkandMocha。如果每种搭配都是一个类,那么随着咖啡和调料种类的增加,将会出现类爆炸:
此时装饰者模式应运而生,结构图如下:
C++实现:
class Coffee {public: virtual double getCost() = 0; virtual string getDescription() = 0;};class HouseBlend : public Coffee {public: double getCost() { return 1.24; } string getDescription() { return "HouseBlend"; }};class DarkRoast : public Coffee {public: double getCost() { return 2.73; } string getDescription() { return "DarkRoast"; }};class CoffeeDecorator : public Coffee {private: Coffee *decoratedCoffee;public: CoffeeDecorator(Coffee *c): decoratedCoffee(c) {} double getCost() { return decoratedCoffee->getCost(); } string getDescription() { return decoratedCoffee->getDescription(); }};class Milk : public CoffeeDecorator {public: Milk(Coffee *c): CoffeeDecorator(c) {} double getCost() { return CoffeeDecorator::getCost() + 0.5; } string getDescription() { return CoffeeDecorator::getDescription() + ", Milk"; }};class Mocha : public CoffeeDecorator {public: Mocha(Coffee *c): CoffeeDecorator(c) {} double getCost() { return CoffeeDecorator::getCost() + 0.7; } string getDescription() { return CoffeeDecorator::getDescription() + ", Mocha"; }};int main(){ Coffee *pc = new HouseBlend; cout << "description: " << pc->getDescription() << " cost: " << pc->getCost() << endl; pc = new Milk(pc); cout << "description: " << pc->getDescription() << " cost: " << pc->getCost() << endl; pc = new Mocha(pc); cout << "description: " << pc->getDescription() << " cost: " << pc->getCost() << endl; delete pc;}
装饰者模式的一个特征是:装饰者和被装饰对象具有相同的超类型。
reference: