动机

  • 在某些情况下我们可能会“过度地使用继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。
  • 如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响降为最低?

    模式定义

    动态(组合)地给一个对象增加一些额外地职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码&减少子类个数)。

    未使用该设计模式

    ```cpp //业务操作 class Stream{ public: virtual char Read(int number) = 0; virtual void Seek(int position) = 0; virtual void Write(char data) = 0;

    virtual ~Stream() {} };

//主体类 class FileStream : public Stream { public: virtual char Read(int number) { //读文件流 } virtual void Seek(int position) { //定位文件流 } virtual void Write(char data) { //写文件流 } };

class NetworkStream : public Stream { public: virtual char Read(int number) { //读文件流 } virtual void Seek(int position) { //定位文件流 } virtual void Write(char data) { //写文件流 } };

class MemoryStream : public Stream { public: virtual char Read(int number) { //读文件流 } virtual void Seek(int position) { //定位文件流 } virtual void Write(char data) { //写文件流 } };

//扩展操作 class CrytoFileStream : public FileStream { public: virtual char Read(int number) { //额外的加密操作 FileStream::Read(number); //读文件流 //额外的加密操作 } virtual void Seek(int position) { //额外的加密操作 FileStream::Seek(position); //定位文件流 //额外的加密操作 } virtual void Write(char data) { //额外的加密操作 FileStream::Write(data); //写文件流 //额外的加密操作 } };

//扩展操作 class CrytoNetworkStream : public NetworkStream { public: virtual char Read(int number) { //额外的加密操作 //(59,80,101行代码相同,导致代码冗余) NetworkStream::Read(number); //读文件流 //额外的加密操作 } virtual void Seek(int position) { //额外的加密操作 NetworkStream::Seek(position); //定位文件流 //额外的加密操作 } virtual void Write(char data) { //额外的加密操作 NetworkStream::Write(data); //写文件流 //额外的加密操作 } };

//扩展操作 class CrytoMemoryStream : public MemoryStream { public: virtual char Read(int number) { //额外的加密操作 MemoryStream::Read(number); //读文件流 //额外的加密操作 } virtual void Seek(int position) { //额外的加密操作 MemoryStream::Seek(position); //定位文件流 //额外的加密操作 } virtual void Write(char data) { //额外的加密操作 MemoryStream::Write(data); //写文件流 //额外的加密操作 } };

class BufferedFileStream : public FileStream { //… }; class BufferedNetworkStream : public NetworkStream { //… }; class BufferedMemoryStream : public MemoryStream { //… };

class CrytoBufferedFileStream : public FileStream { public: virtual char Read(int number) { //额外的加密操作 //额外的缓存操作 FileStream::Read(number); //读文件流 //额外的加密操作 //额外的缓存操作 } virtual void Seek(int position) { //额外的加密操作 //额外的缓存操作 FileStream::Seek(position); //定位文件流 //额外的加密操作 //额外的缓存操作 } virtual void Write(char data) { //额外的加密操作 //额外的缓存操作 FileStream::Write(data); //写文件流 //额外的加密操作 //额外的缓存操作 } };

void Process() { // 编译时装配 CrytoFileStream* fs1 = new CrytoFileStream();

  1. BufferedFileStream* fs2 = new BufferedFileStream();
  2. CrytoBufferedFileStream *fs3 = new CrytoBufferedFileStream();

}

  1. <a name="Q0rBY"></a>
  2. #### 存在的问题
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2719428/1622965793834-212468cb-1d79-4bd8-b8be-a9a363eb4af0.png#align=left&display=inline&height=404&margin=%5Bobject%20Object%5D&name=image.png&originHeight=539&originWidth=1210&size=346774&status=done&style=none&width=908)
  4. <a name="l2yyB"></a>
  5. ### 实现2
  6. ```cpp
  7. //业务操作
  8. class Stream{
  9. public:
  10. virtual char Read(int number) = 0;
  11. virtual void Seek(int position) = 0;
  12. virtual void Write(char data) = 0;
  13. virtual ~Stream() {}
  14. };
  15. //主体类
  16. class FileStream : public Stream
  17. {
  18. public:
  19. virtual char Read(int number) {
  20. //读文件流
  21. }
  22. virtual void Seek(int position) {
  23. //定位文件流
  24. }
  25. virtual void Write(char data) {
  26. //写文件流
  27. }
  28. };
  29. class NetworkStream : public Stream
  30. {
  31. public:
  32. virtual char Read(int number) {
  33. //读文件流
  34. }
  35. virtual void Seek(int position) {
  36. //定位文件流
  37. }
  38. virtual void Write(char data) {
  39. //写文件流
  40. }
  41. };
  42. class MemoryStream : public Stream
  43. {
  44. public:
  45. virtual char Read(int number) {
  46. //读文件流
  47. }
  48. virtual void Seek(int position) {
  49. //定位文件流
  50. }
  51. virtual void Write(char data) {
  52. //写文件流
  53. }
  54. };
  55. //扩展操作
  56. /*合并*/
  57. //class CrytoFileStream
  58. //{
  59. // Stream* stream; //= new FileStream();
  60. //public:
  61. // virtual char Read(int number) {
  62. // //额外的加密操作 //(59,80,101行代码相同,导致代码冗余)
  63. // stream->Read(number); //读文件流
  64. // //额外的加密操作
  65. // }
  66. // virtual void Seek(int position) {
  67. // //额外的加密操作
  68. // stream->Seek(position); //定位文件流
  69. // //额外的加密操作
  70. // }
  71. // virtual void Write(char data) {
  72. // //额外的加密操作
  73. // stream->Write(data); //写文件流
  74. // //额外的加密操作
  75. // }
  76. //};
  77. //
  78. ////扩展操作
  79. //class CrytoNetworkStream
  80. //{
  81. // Stream* stream; //= New NetworkStream();
  82. //public:
  83. // virtual char Read(int number) {
  84. // //额外的加密操作
  85. // stream->Read(number); //读文件流
  86. // //额外的加密操作
  87. // }
  88. // virtual void Seek(int position) {
  89. // //额外的加密操作
  90. // stream->Seek(position); //定位文件流
  91. // //额外的加密操作
  92. // }
  93. // virtual void Write(char data) {
  94. // //额外的加密操作
  95. // stream->Write(data); //写文件流
  96. // //额外的加密操作
  97. // }
  98. //};
  99. //
  100. ////扩展操作
  101. //class CrytoMemoryStream
  102. //{
  103. // Stream* stream; //= new MemoryStream();
  104. //public:
  105. // virtual char Read(int number) {
  106. // //额外的加密操作
  107. // stream->Read(number); //读文件流
  108. // //额外的加密操作
  109. // }
  110. // virtual void Seek(int position) {
  111. // //额外的加密操作
  112. // stream->Seek(position); //定位文件流
  113. // //额外的加密操作
  114. // }
  115. // virtual void Write(char data) {
  116. // //额外的加密操作
  117. // stream->Write(data); //写文件流
  118. // //额外的加密操作
  119. // }
  120. //};
  121. class CryptoStream : public Stream
  122. {
  123. Stream* stream; //...
  124. public:
  125. CryptoStream(Stream* stm) :stream(stm)
  126. {
  127. }
  128. virtual char Read(int number) {
  129. //额外的加密操作
  130. stream->Read(number); //读文件流
  131. //额外的加密操作
  132. }
  133. virtual void Seek(int position) {
  134. //额外的加密操作
  135. stream->Seek(position); //定位文件流
  136. //额外的加密操作
  137. }
  138. virtual void Write(char data) {
  139. //额外的加密操作
  140. stream->Write(data); //写文件流
  141. //额外的加密操作
  142. }
  143. };
  144. /*合并*/
  145. //class BufferedFileStream : public FileStream {
  146. // //...
  147. //};
  148. //class BufferedNetworkStream : public NetworkStream {
  149. // //...
  150. //};
  151. //class BufferedMemoryStream : public MemoryStream {
  152. // //...
  153. //};
  154. class BufferedStream : public Stream {
  155. Stream* stream;
  156. public:
  157. BufferedStream(Stream* stm) :stream(stm)
  158. {
  159. }
  160. virtual char Read(int number) {
  161. //额外的传冲操作
  162. stream->Read(number); //读文件流
  163. //额外的传冲操作
  164. }
  165. virtual void Seek(int position) {
  166. //额外的传冲操作
  167. stream->Seek(position); //定位文件流
  168. //额外的传冲操作
  169. }
  170. virtual void Write(char data) {
  171. //额外的传冲操作
  172. stream->Write(data); //写文件流
  173. //额外的传冲操作
  174. }
  175. };
  176. void Process() {
  177. // 运行时装配
  178. FileStream* s1 = new FileStream();
  179. CryptoStream* s2 = new CryptoStream(s1);
  180. BufferedStream* s3 = new BufferedStream(s1);
  181. BufferedStream* s4 = new BufferedStream(s2);
  182. }

实现3

  1. //业务操作
  2. class Stream{
  3. public:
  4. virtual char Read(int number) = 0;
  5. virtual void Seek(int position) = 0;
  6. virtual void Write(char data) = 0;
  7. virtual ~Stream() {}
  8. };
  9. //主体类
  10. class FileStream : public Stream
  11. {
  12. public:
  13. virtual char Read(int number) {
  14. //读文件流
  15. }
  16. virtual void Seek(int position) {
  17. //定位文件流
  18. }
  19. virtual void Write(char data) {
  20. //写文件流
  21. }
  22. };
  23. class NetworkStream : public Stream
  24. {
  25. public:
  26. virtual char Read(int number) {
  27. //读文件流
  28. }
  29. virtual void Seek(int position) {
  30. //定位文件流
  31. }
  32. virtual void Write(char data) {
  33. //写文件流
  34. }
  35. };
  36. class MemoryStream : public Stream
  37. {
  38. public:
  39. virtual char Read(int number) {
  40. //读文件流
  41. }
  42. virtual void Seek(int position) {
  43. //定位文件流
  44. }
  45. virtual void Write(char data) {
  46. //写文件流
  47. }
  48. };
  49. class DecoratorStream : public Stream
  50. {
  51. protected:
  52. Stream* stream; //...
  53. DecoratorStream(Stream* stm) : stream(stm)
  54. {
  55. }
  56. };
  57. class CryptoStream : public DecoratorStream
  58. {
  59. public:
  60. CryptoStream(Stream* stm) : DecoratorStream(stm)
  61. {
  62. }
  63. virtual char Read(int number) {
  64. //额外的加密操作
  65. stream->Read(number); //读文件流
  66. //额外的加密操作
  67. }
  68. virtual void Seek(int position) {
  69. //额外的加密操作
  70. stream->Seek(position); //定位文件流
  71. //额外的加密操作
  72. }
  73. virtual void Write(char data) {
  74. //额外的加密操作
  75. stream->Write(data); //写文件流
  76. //额外的加密操作
  77. }
  78. };
  79. class BufferedStream : public DecoratorStream {
  80. public:
  81. BufferedStream(Stream* stm) : DecoratorStream(stm)
  82. {
  83. }
  84. virtual char Read(int number) {
  85. //额外的传冲操作
  86. stream->Read(number); //读文件流
  87. //额外的传冲操作
  88. }
  89. virtual void Seek(int position) {
  90. //额外的传冲操作
  91. stream->Seek(position); //定位文件流
  92. //额外的传冲操作
  93. }
  94. virtual void Write(char data) {
  95. //额外的传冲操作
  96. stream->Write(data); //写文件流
  97. //额外的传冲操作
  98. }
  99. };
  100. void Process() {
  101. // 运行时装配
  102. FileStream* s1 = new FileStream();
  103. CryptoStream* s2 = new CryptoStream(s1);
  104. BufferedStream* s3 = new BufferedStream(s1);
  105. BufferedStream* s4 = new BufferedStream(s2);
  106. }

image.png
image.png