在 OO 设计和开发过程,可能会经常遇到以下的情况:我们需要为一个已经定义好的类 添加新的职责(操作),通常的情况我们会给定义一个新类继承自定义好的类,这样会带来 一个问题(将在本模式的讨论中给出)。通过继承的方式解决这样的情况还带来了系统的复 杂性,因为继承的深度会变得很深。而 Decorator 提供了一种给类增加职责的方法,不是通过继承实现的,而是通过组合。
问题提出 现在假设要实现一个 I/O 的库,针对一些流(Stream)进行操作,如文件流(FileStream)、网络流(NetwordStream)、内存流(MemoryStream)等,同时还要对各种流进行额外的扩展操作,如加密(Crypto)、缓存(Buffered)等
1.0 版本 下面是第一种解决此问题的方式,设计一个流的基类 Stream,文件流、网络流、内存流都继承于 Stream 类来实现各自的功能,再通过继承文件流、网络流、内存流实现相应的加密xx流、缓存xx流以及加密缓存xx流……
下面是这种实现方式的类图
看到这样一张图,应该已经能意识到这种实现方式存在的缺陷了,如果有 n 个如文件流这样的主题功能,m 个如加密这样的扩展功能,那么最后要实现的类的个数将会达到 ( Cm 1 + Cm 2 + … + Cm m ) x n + n + 1 个,如此众多的类令人眼花缭乱,其中势必还充斥着大量的重复代码(加密、缓存的算法),从而使代码变得更加复杂。
下面是实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 class Stream { public : virtual void Read () = 0 ; virtual void Write () = 0 ; virtual void Seek () = 0 ; }; class FileStream : public Stream{ public : virtual void Read () { } virtual void Write () { } virtual void Seek () { } }; class NetworkStream : public Stream{ public : virtual void Read () { } virtual void Write () { } virtual void Seek () { } }; class MemoryStream : public Stream{ public : virtual void Read () { } virtual void Write () { } virtual void Seek () { } }; class CryptoFileStream : public FileStream{ public : virtual void Read () { FileStream::Read (); } virtual void Write () { FileStream::Write (); } virtual void Seek () { FileStream::Seek (); } }; class CryptoNetWorkStream : public NetworkStream{ public : virtual void Read () { NetworkStream::Read (); } virtual void Write () { NetworkStream::Write (); } virtual void Seek () { NetworkStream::Seek (); } }; class CryptoMemoryStream : public MemoryStream{ public : virtual void Read () { MemoryStream::Read (); } virtual void Write () { MemoryStream::Write (); } virtual void Seek () { MemoryStream::Seek (); } }; class BufferedFileStream : public FileStream{ public : virtual void Read () { FileStream::Read (); } virtual void Write () { FileStream::Write (); } virtual void Seek () { FileStream::Seek (); } }; class BufferedNetWorkStream : public NetworkStream{ public : virtual void Read () { NetworkStream::Read (); } virtual void Write () { NetworkStream::Write (); } virtual void Seek () { NetworkStream::Seek (); } }; class BufferedMemoryStream : public MemoryStream{ public : virtual void Read () { MemoryStream::Read (); } virtual void Write () { MemoryStream::Write (); } virtual void Seek () { MemoryStream::Seek (); } }; class CryptoBufferedFileStream : public FileStream{ public : virtual void Read () { FileStream::Read (); } virtual void Write () { FileStream::Write (); } virtual void Seek () { FileStream::Seek (); } }; class CryptoBufferedNetWorkStream : public NetworkStream{ public : virtual void Read () { NetworkStream::Read (); } virtual void Write () { NetworkStream::Write (); } virtual void Seek () { NetworkStream::Seek (); } }; class CryptoBufferedMemoryStream : public MemoryStream{ public : virtual void Read () { MemoryStream::Read (); } virtual void Write () { MemoryStream::Write (); } virtual void Seek () { MemoryStream::Seek (); } }; int main () { FileStream* s1 = new FileStream (); CryptoFileStream* s2 = new CryptoFileStream (); BufferedFileStream* s3 = new BufferedFileStream (); CryptoBufferedFileStream* s4 = new CryptoBufferedFileStream (); return 0 ; }
2.0 版本 下面的代码使用了装饰模式的设计思想,在处理加密和缓存功能的问题上,用组合的方式取代了原来的继承方式,现在想要在文件流的基础上实现加密、缓存等操作,只要把文件流的指针传给相应的功能类即可完成额外的工作。
这种实现方式的类层次结构图如图所示
代码实现如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 class Stream { public : virtual void Read () = 0 ; virtual void Write () = 0 ; virtual void Seek () = 0 ; }; class FileStream : public Stream{ public : virtual void Read () { } virtual void Write () { } virtual void Seek () { } }; class NetworkStream : public Stream{ public : virtual void Read () { } virtual void Write () { } virtual void Seek () { } }; class MemoryStream : public Stream{ public : virtual void Read () { } virtual void Write () { } virtual void Seek () { } }; class CryptoStream : public Stream{ Stream* stream; public : CryptoStream (Stream* stm) : stream (stm) { } virtual void Read () { stream->Read (); } virtual void Write () { stream->Write (); } virtual void Seek () { stream->Seek (); } }; class BufferedStream : public Stream{ Stream* stream; public : BufferedStream (Stream* stm) : stream (stm) { } virtual void Read () { stream->Read (); } virtual void Write () { stream->Write (); } virtual void Seek () { stream->Seek (); } }; int main () { FileStream* s1 = new FileStream (); CryptoStream* s2 = new CryptoStream (s1); BufferedStream* s3 = new BufferedStream (s1); BufferedStream* s4 = new BufferedStream (s2); return 0 ; }
3.0 版本 在 GoF 设计模式中,将组合在各个类中的指针 Stream* stream
放到了一个顶层类中,类层次结构图如下:
代码实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 class Stream { public : virtual void Read () = 0 ; virtual void Write () = 0 ; virtual void Seek () = 0 ; }; class FileStream : public Stream{ public : virtual void Read () { } virtual void Write () { } virtual void Seek () { } }; class NetworkStream : public Stream{ public : virtual void Read () { } virtual void Write () { } virtual void Seek () { } }; class MemoryStream : public Stream{ public : virtual void Read () { } virtual void Write () { } virtual void Seek () { } }; class DecoratorStream : public Stream{ protected : Stream* stream; DecoratorStream (Stream* stm) : stream (stm) { } }; class CryptoStream : public DecoratorStream{ public : CryptoStream (Stream* stm) : DecoratorStream (stm) { } virtual void Read () { stream->Read (); } virtual void Write () { stream->Write (); } virtual void Seek () { stream->Seek (); } }; class BufferedStream : public DecoratorStream{ public : BufferedStream (Stream* stm) : DecoratorStream (stm) { } virtual void Read () { stream->Read (); } virtual void Write () { stream->Write (); } virtual void Seek () { stream->Seek (); } }; int main () { FileStream* s1 = new FileStream (); CryptoStream* s2 = new CryptoStream (s1); BufferedStream* s3 = new BufferedStream (s1); BufferedStream* s4 = new BufferedStream (s2); return 0 ; }
总结 最后附上一张装饰器模式(Decorator Pattern)的类图