读《大话设计模式》---装饰模式(decorator)

装饰模式

动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。

 

一般的实现代码

  1. class Component
  2. {
  3. public:
  4.       //纯虚类  
  5.        virtual void Operation() = 0;
  6. };
  7. class ConcreteComponent : public  Component
  8. {
  9. public:
  10.       virtual void Operation()
  11.       {
  12.               cout << "具体对象的操作" << endl;
  13.       }
  14. };
  15. class Decorator : Component
  16. {
  17. protected:
  18.        Component * component;
  19. public:
  20.        void SetComponent(Component * component)
  21.        {
  22.                this->compontent = component;
  23.        } 
  24.        //重写 Operation(),实际执行的是Component的Operation()  
  25.        virtual void Operation()
  26.        {
  27.                 component->Operation();
  28.        } 
  29. }
  30. class ConcreteDecoratorA : Decorator
  31. {
  32. private:
  33.          //本类的独有功能,区别于ConcreteDecoratorB  
  34.          string addedState;
  35. public:
  36.          virtual void Operation()
  37.          {
  38.                  //首先运行原Component的Opretion (),再执行本类的功能,如addedState,相当于对原Component进行了装饰。  
  39.                  Component::Operation();
  40.                  addedState = "New State";
  41.                  cout << "具体装饰对象A的操作";
  42.           }
  43. }
  44. class ConcreteDecoratorB : Decorator
  45. {
  46. public:
  47.          virtual void Operation()
  48.          {
  49.                  //首先运行原Component的Opretion (),再执行本类的功能,如addedBehavior(),相当于对原Component进行了装饰。  
  50.                  Component::Operation();
  51.                  AddedBehavior();
  52.                  cout << "具体装饰对象B的操作";
  53.           }
  54. private:
  55.           void AddedBehavior(){ }
  56. }
  57. int main()
  58. {
  59.           ConcreteComponent  *c = new ConcreteComponent ;
  60.           ConcreteDecoratorA *d1 = new ConcreteComponent ;
  61.           ConcreteDecoratorB *d2 = new ConcreteComponent ;
  62.           //装饰的方法是:首先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA的实例化对象d1来包装c,  
  63.           //再用ConcreteDecoratorB的实例化对象d2来包装d1,最后执行d2的Operation()  
  64.           d1->SetComponent(c);
  65.           d2->SetComponent(d1);
  66.           d2->Operation();
  67.           return 0;
  68. }

装饰模式是利用SetComponent来对对象进行包装的,这样每个装饰对象的实现就和如何使用这个对象分离开了,

每个装饰对象只关心自己的功能,不需要关心如何添加到对象中去。

 

一个具体的实现代码:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class Person
  5. {
  6. public:
  7.  Person(){};
  8.  Person(string name)
  9.  {
  10.   this->name = name;
  11.  }
  12.  virtual void Show()
  13.  {
  14.   cout << "装扮的" << name << endl;
  15.  }
  16. private:
  17.  string name;
  18. };
  19. class Finery : public Person
  20. {
  21. protected:
  22.  Person * component;
  23.  //打扮
  24. public:
  25.  void Decorate(Person * component)
  26.  {
  27.   this->component = component;
  28.  }
  29.  virtual void Show()
  30.  {
  31.   component->Show();
  32.  }
  33. };
  34. //具体服装类(ConcreteDecorator)
  35. class TShirts : public Finery
  36. {
  37. public:
  38.  virtual void Show()
  39.  {
  40.   cout << "大T恤 ";
  41.   Finery::Show();
  42.  }
  43. };
  44. class BigTrouser : public Finery
  45. {
  46. public:
  47.  virtual void Show()
  48.  {
  49.   cout << "垮裤 ";
  50.   Finery::Show();
  51.  }
  52. };
  53. class Sneakers : public Finery
  54. {
  55. public:
  56.  virtual void Show()
  57.  {
  58.   cout << "破球鞋 ";
  59.   Finery::Show();
  60.  }
  61. };
  62. class BusinessSuit : public Finery
  63. {
  64. public:
  65.  virtual void Show()
  66.  {
  67.   cout << "西装 ";
  68.   Finery::Show();
  69.  }
  70. };
  71. class necktie : public Finery
  72. {
  73. public:
  74.  virtual void Show()
  75.  {
  76.   cout << "领带 ";
  77.   Finery::Show();
  78.  }
  79. };
  80. class Shoeleather : public Finery
  81. {
  82. public:
  83.  virtual void Show()
  84.  {
  85.   cout << "皮鞋 ";
  86.   Finery::Show();
  87.  }
  88. };
  89. int main(int argc, char* argv[])
  90. {
  91.  Person * xc = new Person("小菜");
  92.  cout << "第一种装扮: " << endl;
  93.     TShirts    *ts = new TShirts();
  94.     BigTrouser *bt = new BigTrouser();
  95.     Sneakers   *sk = new Sneakers();
  96.  ts->Decorate(xc);
  97.  bt->Decorate(ts);
  98.  sk->Decorate(bt);
  99.  sk->Show();
  100.  return 0;
  101. }
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值