C++设计模式05 —— 装饰模式

发布时间 2024-01-10 17:03:30作者: Torch_HXM

装饰模式

  • 过度的使用继承使得派生的子类过多,代码重复度很高,复用性变差。

  • 实现加密文件流、加密网络流、加密内存流、缓冲文件流、缓冲网络流、缓冲内存流。

    • 如果我们创建一个流基类,然后创建文件流继承流基类,最后创建加密文件流继承文件流、创建缓冲文件流继承文件流。如果这样,则对于文件、网络、内存我们就需要创建总共 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);
    }
};