背景:在软件开发,如果责任划分的不清楚,是继承得到随着需求的变化子类会急剧膨胀,同时充斥着重复的代码这时候关键是需要划清责任
动机:在某些情况下我们可能过度的使用继承来扩展对象的功能,由于继承为类型引用的静态特性,是的这种扩展缺乏灵活性;并且随着子类的加多,各个子类的组合会导致更多子类的膨胀;
问题:如何是的对象的功能扩展能根据需求动态的实现呢?同时避免“扩展的功能增多”子类个数膨胀呢?从而使“功能扩展”带来的影响最小呢?
如下列子是对流的炒作,有文件流和网络流牟其中文件流还有加密文件流,缓存文件流,加密缓存文件流,网络流也有加密文件流,缓存网络流,加密缓存网络流;因为错误的使用继承,在1.0版本中会有大量的子类膨胀,代码盈余;2.0版本已经得到了优化;
1.0版本:
#pragma once
#pragma once
#include<iostream>
using namespace std;
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)
{
cout << "FileStream Read...." << endl;
}
virtual void Seek(int position)
{
cout << "FileStream Seek..." << endl;
}
virtual void Write(char data)
{
cout << "FileStream Write..." << endl;
}
};
//网络流
class NetWorkStream :public Stream
{
public:
virtual char Read(int number)
{
cout << "NetWorkStream Read...." << endl;
}
virtual void Seek(int position)
{
cout << "NetWorkStream Seek..." << endl;
}
virtual void Write(char data)
{
cout << "NetWorkStream Write..." << endl;
}
};
//扩展功能对流进行加密,文件流缓存,文件流加密并且缓存
/*
对文件流加密
*/
class CryptFileStream :public FileStream
{
public:
virtual char Read(int number)
{
cout << "FileStream Read..." << "and ";
cout << "CryptFileStream..." << endl;
}
};
class BufferFileStream :public FileStream
{
public:
virtual char Read(int number)
{
cout << "FileStream Read..." << " and ";
cout << "BufferFileStream..." << endl;
}
};
class CryptBufferFileStream :public FileStream
{
public:
virtual char Read(int number)
{
cout << "FileStream Read..." << " and ";
cout << "CryptBufferFileStream..." << endl;
}
};
//对网络流加密,缓存,缓存加加密
class CryptNetWorkStream :public NetWorkStream
{
public:
virtual char Read(int number)
{
cout << "NetWorkStream Read..." << "and ";
cout << "CryptNetWorkStream..." << endl;
}
};
class BufferNetWorkStream :public NetWorkStream
{
public:
virtual char Read(int number)
{
cout << "NetWorkStream Read..." << " and ";
cout << "BufferNetWorkStream..." << endl;
}
};
class CryptNetWorkStream :public NetWorkStream
{
public:
virtual char Read(int number)
{
cout << "NetWorkStream Read..." << " and ";
cout << "CryptNetWorkStream..." << endl;
}
};
//扩展功能对流进行加密,文件流缓存,文件流加密并且缓存
/*
对文件流加密
*/
/*
1、不管是对文件流的加密还是对网络流的加密,加密方法是一样的;
此时观察CryptFileStream 和 CryptNetWorkStream除了调用各自子类的Read方法,其他都一样;试用组合看看怎么样
2、改成基类的组合后,发现组合的各自的子类可以在找上一层的子类,fileStream基类Stream;因为fileStream继承Stream;未来可以实现指向FileStream;
*/
/*class CryptFileStream
{
public:
CryptFileStream(FileStream* stream) :stream(stream)
{}
private:
FileStream* stream;
public:
virtual char Read(int number)
{
stream->Read(10);
cout << "CryptStream...." << endl;
}
};*/
// ||
class CryptFileStream
{
public:
CryptFileStream(Stream* stream) :stream(stream)
{}
private:
Stream* stream; // stream = newFileStream();
public:
virtual char Read(int number)
{
stream->Read(10);
cout << "CryptStream...." << endl;
}
};
class BufferFileStream :public FileStream
{
public:
virtual char Read(int number)
{
FileStream::Read(10);
cout << "BufferFileStream..." << endl;
}
};
class CryptBufferFileStream :public FileStream
{
public:
virtual char Read(int number)
{
FileStream::Read(10);
cout << "CryptBufferFileStream..." << endl;
}
};
//对网络流加密,缓存,缓存加加密
//class CryptNetWorkStream
//{
//public:
//CryptNetWorkStream(NetWorkStream* stream) :stream(stream)
//{}
//private:
//NetWorkStream* stream;
//public:
//virtual char Read(int number)
//{
//stream->Read(10);
//cout << "CryptStream......." << endl;
//}
//};
//|| 上面等价于下面
class CryptNetWorkStream
{
public:
CryptNetWorkStream(Stream* stream) :stream(stream)
{}
private:
Stream* stream;// new NetWorkStream();
public:
virtual char Read(int number)
{
stream->Read(10);
cout << "CryptStream......." << endl;
}
};
//此时在看CryptFileStream 和 CryptNetWorkStream发现一模一样;
//2.0版本
//直接合并成一个类:
/*class CryptStream
{
public:
CryptStream(Stream* stream) :stream(stream)
{}
private:
Stream* stream;
public:
virtual char Read(int number)
{
stream->Read(10);
cout << "CryptStream......." << endl;
return 'c';
}
};
//我们来测试下
//因此对流的缓存 保留一个类即可;
class BufferNetWorkStream :public NetWorkStream
{
public:
virtual char Read(int number)
{
NetWorkStream::Read(10);
cout << "BufferNetWorkStream..." << endl;
}
};
//如下所示:
class BufferStream
{
public:
BufferStream(Stream* stream) :stream(stream)
{}
private:
Stream* stream;
public:
virtual char Read(int number)
{
stream->Read(10);
cout << "BufferStream......." << endl;
return 'c';
}
};
class CryptBufferNetWorkStream :public NetWorkStream
{
public:
virtual char Read(int number)
{
NetWorkStream::Read(10);
cout << "CryptNetWorkStream..." << endl;
}
};
//缓存加密也只需要保留一个类即可
class CryptBufferStream
{
public:
CryptBufferStream(Stream* stream) :stream(stream)
{}
private:
Stream* stream;
public:
virtual char Read(int number)
{
stream->Read(10);
cout << "CryptBufferStream......." << endl;
return 'c';
}
};
//不管是加密、缓存、缓存加密操作还需要的seek、write操作因此还需要继承Stream类;
class CryptStream:public Stream
{
public:
CryptStream(Stream* stream) :stream(stream)
{}
private:
Stream* stream;
public:
virtual char Read(int number)
{
stream->Read(10);
return 'c';
}
virtual void Seek(int position)
{
stream->Seek(10);
}
virtual void Write(char data)
{
stream->Write(10);
}
};
class BufferStream :public Stream
{
public:
BufferStream(Stream* stream) :stream(stream)
{}
private:
Stream* stream;
public:
virtual char Read(int number)
{
stream->Read(10);
return 'c';
}
virtual void Seek(int position)
{
stream->Seek(10);
}
virtual void Write(char data)
{
stream->write(10);
}
};*/
#include"Stream_2.h"
void main()
{
Stream* stream = new FileStream();
CryptStream* cryptstream = new CryptStream(stream);
cryptstream->Read(10);
stream = new NetWorkStream();
cryptstream = new CryptStream(stream);
cryptstream->Read(10);
}
/3.0版本
/*但是CryptStream 和 BufferStream都含有Stream 这个字段,所以可以单独拎出来放在一个类中,省的每个类都写;
为什么不把Stream* stream;直接放在Stream中呢,因为FileStream 和 NetStrean不需要
因此需要中间类DecoratStream
*/
//统一实现Seek、Write方法;
class DecoratStream :public Stream
{
protected:
Stream* stream;
public:
DecoratStream(Stream* stream) :stream(stream)
{}
virtual char Read(int number)
{
stream->Read(10);
return 'c';
}
virtual void Seek(int position)
{
stream->Seek(10);
}
virtual void Write(char data)
{
stream->Write(10);
}
};
//CryptStream 、BufferStream继承DecoratStream就可以了;
class CryptStream :public DecoratStream
{
public:
CryptStream(Stream* stream) :DecoratStream(stream)
{}
public:
virtual char Read(int number)
{
stream->Read(10);
cout << "CryptStream......." << endl;
return 'c';
}
};
class BufferStream :public DecoratStream
{
public:
BufferStream(Stream* stream) :DecoratStream(stream)
{}
public:
virtual char Read(int number)
{
stream->Read(10);
cout << "BufferStream......." << endl;
return 'c';
}
};
//测试一下