设计模式 - 装饰模式(Decorator)

    在软件设计中,如果责任划分不清晰,需求的变化时,子类会急剧膨胀,代码会大量重复。此时,划分责任是最关键的做法。

定义

    动态的给一个对象增加职责,装饰模式比继承更加灵活。它能消除重复代码和减少子类个数。

实例

     先看下面代码存在的问题。(子类膨胀,重复代码)

     有文件流,网络流,加密流三种数据流,而每种数据流有加密,缓冲,加密且缓冲三种操作。

     数据流的定义如下:

class Stream
{
public:
    virtual char Read() = 0;
    virtual void Write(char data) = 0;
    virtual ~Stream(){}
};

//文件流
class FileStream :public Stream
{
public:
    virtual char Read() override{};
    virtual void Write(char data) override {};
    virtual ~FileStream() {}
};

//网络流
class NetworkStream :public Stream
{
public:
    virtual char Read() override {};
    virtual void Write(char data) override {};
    virtual ~NetworkStream() {}
};

//内存流
class MemoryStream :public Stream
{
public:
    virtual char Read() override {};
    virtual void Write(char data) override {};
    virtual ~MemoryStream() {}
};

   对数据流操作,定义如下:

//加密文件流
class CryptoFileStream :public FileStream
{
public:
    virtual char Read() override
    {
        //加密操作
        FileStream::Read();     
    };
    virtual void Write(char data) override 
    {
        //加密操作
        FileStream::Write(data);
    };
    virtual ~CryptoFileStream() 
    {
    }
};

//加密网络流
class CryptoNetworkStream :public NetworkStream
{
public:
    virtual char Read() override
    {
        //加密操作
        NetworkStream::Read();
    };
    virtual void Write(char data) override
    {
        //加密操作
        NetworkStream::Write(data);
    };
    virtual ~CryptoNetworkStream()
    {
    }
};

//加密内存流
class CryptoMemoryStream :public MemoryStream
{
public:
    virtual char Read() override
    {
        //加密操作
        MemoryStream::Read();
    };
    virtual void Write(char data) override
    {
        //加密操作
        MemoryStream::Write(data);
    };
    virtual ~CryptoMemoryStream()
    {
    }
};


//缓冲文件流
class BufferFileStream :public FileStream
{
public:
    virtual char Read() override
    {
        //缓冲操作
        FileStream::Read();
    };
    virtual void Write(char data) override
    {
        //缓冲操作
        FileStream::Write(data);
    };
    virtual ~BufferFileStream()
    {
    }
};

//缓冲网络流
class BufferNetworkStream :public NetworkStream
{
public:
    virtual char Read() override
    {
        //缓冲操作
        NetworkStream::Read();
    };
    virtual void Write(char data) override
    {
        //缓冲操作
        NetworkStream::Write(data);
    };
    virtual ~BufferNetworkStream()
    {
    }
};

//缓冲内存流
class BufferMemoryStream :public MemoryStream
{
public:
    virtual char Read() override
    {
        //缓冲操作
        MemoryStream::Read();
    };
    virtual void Write(char data) override
    {
        //缓冲操作
        MemoryStream::Write(data);
    };
    virtual ~BufferMemoryStream()
    {
    }
};

.......

    类的结构图如下:

                       

    上述代码中存在大量的重复代码,原因是将Stream的两个方向上的变化混在了一起,使用了继承而不是组合的方式组织代码。

    下面使用组合的方式改进代码:

//加密流
class CryptoFileStream :public Stream
{
public:
    virtual char Read() override
    {
        //加密操作
        stream->Read();
    };
    virtual void Write(char data) override 
    {
        //加密操作
        stream->Write(data);
    };
    virtual ~CryptoFileStream() 
    {
    }
private:
    Stream *stream;
};


//缓冲文件流
class BufferFileStream :public Stream
{
public:
    virtual char Read() override
    {
        //缓冲操作
        stream->Read();
    };
    virtual void Write(char data) override
    {
        //缓冲操作
        stream->Write(data);
    };
    virtual ~BufferFileStream()
    {
    }
private:
    Stream *stream;
};

    此时,代码已经简化很多,基本满足了需求。

    用装饰模式继续优化上述代码:

//装饰器
class DecoratorStream:public Stream
{
protected:
    Stream *stream;  
};

//加密流
class CryptoFileStream :public DecoratorStream
{
public:
    virtual char Read() override
    {
        //加密操作
        stream->Read();
    };
    virtual void Write(char data) override 
    {
        //加密操作
        stream->Write(data);
    };
    virtual ~CryptoFileStream() 
    {
    }
};

//缓冲文件流
class BufferFileStream :public DecoratorStream
{
public:
    virtual char Read() override
    {
        //缓冲操作
        stream->Read();
    };
    virtual void Write(char data) override
    {
        //缓冲操作
        stream->Write(data);
    };
    virtual ~BufferFileStream()
    {
    }
};

    类的结构图如下:

                    

总结 

    装饰模式(Decorator)主要解决主体在多个方向上扩展的问题。

    通过组合而不是继承的方式,装饰模式(Decorator)动态扩展对象的功能,同时避免了子类膨胀和代码重复的问题。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值