设计模式(六)之装配模式

使用继承的方法,如果职责划分不清晰,子类会急剧膨胀。

动机

过度使用继承的方式会出问题

案例

对各种流需要读写等。

第一种方式

20200717132030

直接采用继承的方式 只要再加一个网络数据流那么就会发生类爆炸

class Stream {
public:
    //读数据流
    virtual char Read(int num) = 0;
    //写数据流
    virtual void Write(char data) = 0;
    //定位数据流
    virtual void Seek(int position) = 0;
    virtual ~Stream(){}
};
 
 
class FileStream:public Stream {
public:
    //读数据流
    virtual char Read(int num) {
        qDebug()<<"读文件"<<endl;
    }
 
    //写数据流
    virtual void Write(char data) {
        qDebug()<<"写文件"<<endl;
    }
 
    //定位数据流
    virtual void Seek(int position) {
         qDebug()<<"定位到文件"<<endl;
    }
 
};
//加密文件
class EncryptFileStream:public FileStream {
public:
    //读数据流
    virtual char Read(int num) {
        qDebug()<<"加密文件"<<endl;
        FileStream::Read(num);
    }
 
    //写数据流
    virtual void Write(char data) {
        qDebug()<<"加密文件"<<endl;
        FileStream::Write(data);
    }
 
    //定位数据流
    virtual void Seek(int position) {
         qDebug()<<"加密文件"<<endl;
         FileStream::Seek(position);
    }
 
};
//缓冲
class BuffFileStream:public FileStream {
public:
    //读数据流
    virtual char Read(int num) {
        qDebug()<<"缓冲文件"<<endl;
        FileStream::Read(num);
    }
 
    //写数据流
    virtual void Write(char data) {
        qDebug()<<"缓冲文件"<<endl;
        FileStream::Write(data);
    }
 
    //定位数据流
    virtual void Seek(int position) {
         qDebug()<<"缓冲文件"<<endl;
         FileStream::Seek(position);
    }
 
};

应用程序

    BuffFileStream bstream ;
    bstream.Read(10);

这里如果我们既需要加密又需要缓冲 而且需要网络流 内存流的时候就需要增加大量的代码

优化

优化第一步 将继承改为组合

 
 
//class Stream {
//public:
//    //读数据流
//    virtual char Read(int num) = 0;
//    //写数据流
//    virtual void Write(char data) = 0;
//    //定位数据流
//    virtual void Seek(int position) = 0;
//    virtual ~Stream(){}
//};
 
 
//class FileStream:public Stream {
//public:
//    //读数据流
//    virtual char Read(int num) {
//        qDebug()<<"读文件"<<endl;
//    }
 
//    //写数据流
//    virtual void Write(char data) {
//        qDebug()<<"写文件"<<endl;
//    }
 
//    //定位数据流
//    virtual void Seek(int position) {
//         qDebug()<<"定位到文件"<<endl;
//    }
 
//};
加密文件
//class EncryptFileStream {
//public:
//    FileStream stream;
//    //读数据流
//    virtual char Read(int num) {
//        qDebug()<<"加密文件"<<endl;
//        stream.Read(num);
//    }
 
//    //写数据流
//    virtual void Write(char data) {
//        qDebug()<<"加密文件"<<endl;
//        stream.Write(data);
//    }
 
//    //定位数据流
//    virtual void Seek(int position) {
//         qDebug()<<"加密文件"<<endl;
//         stream.Seek(position);
//    }
 
//};
缓冲
//class BuffFileStream{
//public:
//    FileStream stream;
//    //读数据流
//    virtual char Read(int num) {
//        qDebug()<<"缓冲文件"<<endl;
//        stream.Read(num);
//    }
 
//    //写数据流
//    virtual void Write(char data) {
//        qDebug()<<"缓冲文件"<<endl;
//        stream.Write(data);
//    }
 
//    //定位数据流
//    virtual void Seek(int position) {
//         qDebug()<<"缓冲文件"<<endl;
//         stream.Seek(position);
//    }
 
//};
 

优化第二步 将具体勒替换为接口 ,编译时变幻为执行时

//class Stream {
//public:
//    //读数据流
//    virtual char Read(int num) = 0;
//    //写数据流
//    virtual void Write(char data) = 0;
//    //定位数据流
//    virtual void Seek(int position) = 0;
//    virtual ~Stream(){}
//};
 
 
//class FileStream:public Stream {
//public:
//    //读数据流
//    virtual char Read(int num) {
//        qDebug()<<"读文件"<<endl;
//    }
 
//    //写数据流
//    virtual void Write(char data) {
//        qDebug()<<"写文件"<<endl;
//    }
 
//    //定位数据流
//    virtual void Seek(int position) {
//         qDebug()<<"定位到文件"<<endl;
//    }
 
//};
加密文件
//class EncryptFileStream: public Stream{
//public:
//    Stream* stream;
//    EncryptFileStream(Stream* stm):stream(stm){}
//    //读数据流
//    virtual char Read(int num) {
//        qDebug()<<"加密文件"<<endl;
//        stream->Read(num);
//    }
 
//    //写数据流
//    virtual void Write(char data) {
//        qDebug()<<"加密文件"<<endl;
//        stream->Write(data);
//    }
 
//    //定位数据流
//    virtual void Seek(int position) {
//         qDebug()<<"加密文件"<<endl;
//         stream->Seek(position);
//    }
 
//};
缓冲
//class BuffFileStream:public Stream{
//public:
//    Stream* stream;
//    BuffFileStream(Stream* stm):stream(stm){}
//    //读数据流
//    virtual char Read(int num) {
//        qDebug()<<"缓冲文件"<<endl;
//        stream->Read(num);
//    }
 
//    //写数据流
//    virtual void Write(char data) {
//        qDebug()<<"缓冲文件"<<endl;
//        stream->Write(data);
//    }
 
//    //定位数据流
//    virtual void Seek(int position) {
//         qDebug()<<"缓冲文件"<<endl;
//         stream->Seek(position);
//    }
 
//};
 
 

//优化第三步 将相同的字段向上抽象
//这里每个都有Stream* stream;
//那我们是不是就要把这个属性放到Stream这个基类中呢?
//不可以的 因为FileStream 或者 NetStream不需要这个属性
//那么这里就抽象一个中间的类Decorate

class Stream {
public:
    //读数据流
    virtual char Read(int num) = 0;
    //写数据流
    virtual void Write(char data) = 0;
    //定位数据流
    virtual void Seek(int position) = 0;
    virtual ~Stream(){}
};
 
 
class FileStream:public Stream {
public:
    //读数据流
    virtual char Read(int num) {
        qDebug()<<"读文件"<<endl;
    }
 
    //写数据流
    virtual void Write(char data) {
        qDebug()<<"写文件"<<endl;
    }
 
    //定位数据流
    virtual void Seek(int position) {
         qDebug()<<"定位到文件"<<endl;
    }
 
};
class Decorate :public Stream {
protected:
    Stream* stream;
public:
    Decorate(Stream * stm):stream(stm){
 
    }
 
};
//加密文件
class EncryptFileStream: public Decorate{
public:
    EncryptFileStream(Stream* stm):Decorate(stm){}
    //读数据流
    virtual char Read(int num) {
        qDebug()<<"加密文件"<<endl;
        stream->Read(num);
    }
 
    //写数据流
    virtual void Write(char data) {
        qDebug()<<"加密文件"<<endl;
        stream->Write(data);
    }
 
    //定位数据流
    virtual void Seek(int position) {
         qDebug()<<"加密文件"<<endl;
         stream->Seek(position);
    }
 
};
//缓冲
class BuffFileStream:public Decorate{
public:
    BuffFileStream(Stream* stm):Decorate(stm){}
    //读数据流
    virtual char Read(int num) {
        qDebug()<<"缓冲文件"<<endl;
        stream->Read(num);
    }
 
    //写数据流
    virtual void Write(char data) {
        qDebug()<<"缓冲文件"<<endl;
        stream->Write(data);
    }
 
    //定位数据流
    virtual void Seek(int position) {
         qDebug()<<"缓冲文件"<<endl;
         stream->Seek(position);
    }
 
};

20200717140354

20200717142136

总结 :如果不仅继承一个类而且组合一个类,那么大概率这是一个装饰模式

class Decorate :public Stream {
protected:
    Stream* stream;
public:
    Decorate(Stream * stm):stream(stm){
 
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值