装饰模式
-
过度的使用继承使得派生的子类过多,代码重复度很高,复用性变差。
-
实现加密文件流、加密网络流、加密内存流、缓冲文件流、缓冲网络流、缓冲内存流。
- 如果我们创建一个流基类,然后创建文件流继承流基类,最后创建加密文件流继承文件流、创建缓冲文件流继承文件流。如果这样,则对于文件、网络、内存我们就需要创建总共 10 个类。而且,在这些类中,这些加密和缓冲的操作是重复的。会降低代码的复用性。
- 实际上,我们只需要六个类就可以完成设计,而且极大的提高了代码的服用效率。
写一个流的抽象基类
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 NetStream : public Stream{
public:
virtual char Read(int number){
// ...
}
virtual void Seek(int position){
// ...
}
virtual void Write(char data){
// ...
}
};
class MemStream : public Stream{
public:
virtual char Read(int number){
// ...
}
virtual void Seek(int position){
// ...
}
virtual void Write(char data){
// ...
}
};
写一个通用的加密流,让加密对象在运行时确认
class CryptoStream : public Stream{
private:
Stream* stream;
public:
CryptoStream(Stream* _stream):stream(_stream){}
virtual char Read(int number){
stream->Read(number);
}
virtual void Seek(int position){
stream->Seek(position);
}
virtual void Write(char data){
stream->Write(data);
}
};
写一个通用的缓冲流,让缓冲对象在运行时确认
class BufferStream : public Stream{
private:
Stream* stream;
public:
BufferStream(Stream* _stream):stream(_stream){}
virtual char Read(int number){
stream->Read(number);
}
virtual void Seek(int position){
stream->Seek(position);
}
virtual void Write(char data){
stream->Write(data);
}
};
我们注意到,在 CryptoStream 和 BufferStream 中都包含一个 Stream 字段,因此我们也可以设计一个中间类如下:
class DecoratorStream : public Stream{
protected:
Stream* stream;
public:
DecoratorStream(Stream* stm):stream(stm){}
virtual char Read(int number){}
virtual void Seek(int position){}
virtual void Write(char data){}
virtual ~DecoratorStream(){}
};
然后让 CryptoStream 和 BufferStream 继承 DecoratorStream:
class CryptoStream : public DecoratorStream{
public:
CryptoStream(Stream* _stream):DecoratorStream(_stream){}
virtual char Read(int number){
stream->Read(number);
}
virtual void Seek(int position){
stream->Seek(position);
}
virtual void Write(char data){
stream->Write(data);
}
};
class BufferStream : public DecoratorStream{
public:
BufferStream(Stream* _stream):DecoratorStream(_stream){}
virtual char Read(int number){
stream->Read(number);
}
virtual void Seek(int position){
stream->Seek(position);
}
virtual void Write(char data){
stream->Write(data);
}
};