Headfirst设计模式的C++实现——装饰者模式(Decorater)
Beverage.h
1 #ifndef BEVERAGE_H_INCLUDED 2 #define BEVERAGE_H_INCLUDED 3 4 #include <string> 5 6 class Beverage 7 { 8 public: 9 Beverage( std::string description = "Unknown Beverage" ) : m_description ( description ) {} 10 virtual std::string getDescription() { return m_description; } 11 virtual double cost() = 0; 12 private: 13 std::string m_description; 14 }; 15 16 #endif // BEVERAGE_H_INCLUDED
CondimentDecorator.h
1 #ifndef CONDIMENTDECORATOR_H_INCLUDED 2 #define CONDIMENTDECORATOR_H_INCLUDED 3 4 #include <string> 5 #include "Beverage.h" 6 7 class CondimentDecorator : public Beverage 8 { 9 public: 10 virtual std::string getDescription() = 0; 11 }; 12 13 #endif // CONDIMENTDECORATOR_H_INCLUDED
HouseBlend.h
1 #ifndef HOUSEBLEND_H_INCLUDED 2 #define HOUSEBLEND_H_INCLUDED 3 4 #include "Beverage.h" 5 6 class HouseBlend : public Beverage 7 { 8 public: 9 HouseBlend () : Beverage( "House Blend Coffee" ) {} 10 double cost() { return .89; } 11 }; 12 13 #endif // HOUSEBLEND_H_INCLUDED
Mocha.h
1 #ifndef MOCHA_H_INCLUDED 2 #define MOCHA_H_INCLUDED 3 4 #include "CondimentDecorator.h" 5 6 class Mocha : public CondimentDecorator 7 { 8 public: 9 Mocha ( Beverage * p_beverage ) : m_p_beverage ( p_beverage ) {} 10 std::string getDescription() { return m_p_beverage->getDescription() + ", Mocha"; } 11 double cost() { return .20 + m_p_beverage->cost(); } 12 private: 13 Beverage *m_p_beverage; 14 }; 15 16 #endif // MOCHA_H_INCLUDED
main.cpp
1 #include <iostream> 2 #include "HouseBlend.h" 3 #include "Mocha.h" 4 int main() 5 { 6 HouseBlend house_blend; 7 std::cout << house_blend.getDescription() << ": " << house_blend.cost() << std::endl; 8 9 Mocha mocha_house_blend( &house_blend ); 10 std::cout << mocha_house_blend.getDescription() << ": " << mocha_house_blend.cost() << std::endl; 11 12 Mocha mocha_mocha_house_blend( &mocha_house_blend ); 13 std::cout << mocha_mocha_house_blend.getDescription() << ": " << mocha_mocha_house_blend.cost() << std::endl; 14 15 return 0; 16 }
一点个人理解:
起初对于为什么Mocha类要从CondimentDecorator类继承也就是CondimentDecorator类存在的意义感到疑惑,并做了一次尝试:跳过CondimentDecorator类,让Mocha类直接从Beverage类继承,发现效果是一样的。那为什么还要有CondimentDecorator类的存在呢?
原书上有这么一段解释:
“所有的调料装饰着都必须重新实现getDescription()方法。稍后我们会解释为什么......”
"我们希望叙述不只是描述饮料,而是完整的连调料都描述出来......"
我推测作者的意思是说通过CondimentDecorator类,并且把getDescription方法设置为纯虚函数就可以强制让所有调料类实现此方法。如果不通过getDescription类,那么调料类就可以不实现此方法从而不符合需求。