设计模式(三)--装饰者模式(2)

装饰者模式(Decorator)示例

例子改编自《设计者模式解析(第二版)》214页,人民邮电出版社

 

意图:动态的给一个对象添加职责;即提供了“即插即用”方法,不用重新编译已有部分。

问题:要使用的对象将执行所需的基本功能。但是,可能需要为这个对像添加某些功能,这些附加的功能可能发生在对象的基本功能之前或之后。

解决方案:可以无需创建子类而扩展一个对象的功能

优点:类的层次结构大小和复杂度有了很大程度的降低

缺点:

1)如果装饰者本身是被装饰的,那么访问装饰模式中引进的特性将是非常困难的甚至是危险的。

2)系统对装饰者的使用顺序是敏感的。

附:显然,如果要更改被装饰者的基本功能的情况是不能用装饰者模式的。

参考文献:

[1]《设计者模式解析(第二版)》,人民邮电出版社,Alan Shalloway等著,徐言生译

[2]《设计模式初学者指南》,机械工业出版社,Allen Holub著,徐迎晓译

对示例的描述:

1)具体组件SalesTicket(即被装饰者)实现基本功能(即打印票据正文),需要给它加个表头和表尾,于是用两个具体装饰类Header和Footer完成附加功能。

2)例子改编自参考文献[1],不明白可以看。

3)使用编译器vc6.0通过。

 

01.#include <iostream> 02. 03.using namespace std; 04. 05.//================================================= 06.class Component //抽象组件,即对象的接口 07.{ 08.public: 09. virtual void prtTicket() = 0; 10.}; 11.//================================================= 12.//具体组件,即被装饰者 13.class SalesTicket: public Component 14.{ 15.public: 16. //SalesTicket() 17. //{ 18. // cout<<"构造具体组件SalesTicket/n"<<endl; 19. //} 20. 21. void prtTicket() 22. { 23. cout<<"具体组件SalesTicket打印票据正文/n"<<endl; 24. } 25.}; 26.//================================================= 27.//装饰者(也是抽象组件的子类) 28.class TicketDecorator: public Component 29.{ 30.private: 31. Component* pMyTrailer;//抽象组件作为成员变量 32. 33.public: 34. TicketDecorator(Component& myComponent)//实际使用时,传入构造函数的是具体组件(即被装饰者) 35. { 36. //cout<<"构造装饰者TicketDecorator/n"<<endl; 37. pMyTrailer = NULL; 38. pMyTrailer = &myComponent; 39. } 40. 41. void callTrailer() 42. { 43. if(pMyTrailer != NULL) 44. pMyTrailer->prtTicket(); 45. } 46. 47. //是否需要释放pMyTrailer?????? 48. //如果遵循“谁申请,谁释放”的原则,则不需要 49.}; 50.//================================================= 51.//具体装饰者Header(是装饰者的子类) 52.//功能:打印表头 53.class Header: public TicketDecorator 54.{ 55.public: 56. Header(Component& myComponent):TicketDecorator(myComponent) 57. { 58. //cout<<"构造具体装饰者Header/n"<<endl; 59. } 60. 61. void prtTicket() 62. { 63. //功能:在表的前面加个头部 64. 65. //注意这行代码的位置,在callTrailer()之前 66. //这是装饰者添加的功能 67. cout<<"具体装饰者Header打印表头/n"<<endl; 68. 69. TicketDecorator::callTrailer(); 70. } 71.}; 72. 73.//具体装饰者Footer(是装饰者的子类) 74.//功能:打印表尾 75.class Footer: public TicketDecorator 76.{ 77.public: 78. Footer(Component& myComponent):TicketDecorator(myComponent) 79. { 80. //cout<<"构造具体装饰者Footer/n"<<endl; 81. } 82. 83. void prtTicket() 84. { 85. //功能:在表的后面加个尾部 86. 87. TicketDecorator::callTrailer(); 88. 89. //注意这行代码的位置,在callTrailer()之后 90. //这是装饰者添加的功能 91. cout<<"具体装饰者Footer打印表尾/n"<<endl; 92. } 93.}; 94.//================================================= 95.class Factory//工厂 96.{ 97.public: 98. Component* m_pMyComponent; 99. Component* m_pMyFooter; 100. Component* m_pMyHeader; 101. 102. Factory() 103. { 104. Component* m_pMyComponent = NULL; 105. Component* m_pMyFooter = NULL; 106. Component* m_pMyHeader = NULL; 107. } 108. 109. Component* getComponent() 110. { 111. m_pMyComponent = new SalesTicket(); 112. m_pMyFooter = new Footer(*m_pMyComponent); 113. m_pMyHeader = new Header(*m_pMyFooter); 114. 115. return m_pMyHeader;//返回最后一个指针 116. } 117. 118. ~Factory()//别忘了释放空间 119. { 120. 121. delete m_pMyComponent; 122. delete m_pMyFooter; 123. delete m_pMyHeader; 124. } 125.}; 126.//================================================= 127. 128.int main(int argc, char* argv[]) 129.{ 130. //使用 131. Factory myFactory; 132. Component* pMyComponent = myFactory.getComponent(); 133. pMyComponent->prtTicket();//打印 134. 135. return 0; 136.}

你可能感兴趣的:(设计模式,Decorator,header,null,delete,iostream)