在学习侯捷老师的有关设计模式的课程(李建忠老师主讲)中,老师对23种设计模式的有自己的划分,如下。所以老师讲解是按照这种顺序讲解。
单一职责:
导致更多子类的膨胀
。如下所示,我们有文件流、网络流和内存流3种,都有流需要的read、seek和write
操作。
//业务操作
class Stream{
public:
virtual void Read(int number) = 0;
virtual void Seek(int position) = 0;
virtual void Write(char data) = 0;
virtual ~Stream(){}
};
//主体类
class FileStream : public Stream{
public:
virtual void Read(int number){
//读文件流
cout << "FileStream read" << endl;
}
virtual void Seek(int position){
//定位文件流
cout << "FileStream seak" << endl;
}
virtual void Write(char data){
//写文件流
cout << "FileStream write" << endl;
}
};
class NetworkStream :public Stream{
public:
virtual void Read(int number){
//读网络流
cout << "NetworkStream read" << endl;
}
virtual void Seek(int position){
//定位网络流
cout << "NetworkStream seak" << endl;
}
virtual void Write(char data){
//写网络流
cout << "NetworkStream write" << endl;
}
};
class MemoryStream :public Stream{
public:
virtual void Read(int number){
//读网络流
cout << "MemoryStream read" << endl;
}
virtual void Seek(int position){
//定位网络流
cout << "MemoryStream seak" << endl;
}
virtual void Write(char data){
//写网络流
cout << "MemoryStream write" << endl;
}
};
现在我们需要扩展一下3种流操作,比如说,在read、seek和write
操作时加密,或者是加入缓冲,或者是加密+缓冲。
那么我们很容易会想到用继承的方式实现,如下:
//扩展操作:加密
class CryptoFileStream :public FileStream{
public:
virtual void Read(int number){
//额外的加密操作...
cout << endl << "加密!" << endl;
FileStream::Read(number);//读文件流
}
virtual void Seek(int position){
//额外的加密操作...
cout << endl << "加密!" << endl;
FileStream::Seek(position);//定位文件流
//额外的加密操作...
}
virtual void Write(char data){
//额外的加密操作...
cout << endl << "加密!" << endl;
FileStream::Write(data);//写文件流
//额外的加密操作...
}
};
class CryptoNetworkStream : public NetworkStream{
public:
virtual void Read(int number){
//额外的加密操作...
cout << endl << "加密!" << endl;
NetworkStream::Read(number);//读网络流
}
virtual void Seek(int position){
//额外的加密操作...
cout << endl << "加密!" << endl;
NetworkStream::Seek(position);//定位网络流
//额外的加密操作...
}
virtual void Write(char data){
//额外的加密操作...
cout << endl << "加密!" << endl;
NetworkStream::Write(data);//写网络流
//额外的加密操作...
}
};
class CryptoMemoryStream : public MemoryStream{
public:
virtual void Read(int number){
//额外的加密操作...
cout << endl << "加密!" << endl;
MemoryStream::Read(number);//读内存流
}
virtual void Seek(int position){
//额外的加密操作...
cout << endl << "加密!" << endl;
MemoryStream::Seek(position);//定位内存流
//额外的加密操作...
}
virtual void Write(char data){
//额外的加密操作...
cout << endl << "加密!" << endl;
MemoryStream::Write(data);//写内存流
//额外的加密操作...
}
};
//扩展操作:加缓冲
class BufferedFileStream : public FileStream{
//...
};
class BufferedNetworkStream : public NetworkStream{
//...
};
class BufferedMemoryStream : public MemoryStream{
//...
};
//扩展操作:加密+缓冲
class CryptoBufferedFileStream : public FileStream{
public:
virtual void Read(int number){
//额外的加密操作...
//额外的缓冲操作...
cout << endl << "加密!" << endl;
cout << "缓冲!" << endl;
FileStream::Read(number);//读文件流
}
virtual void Seek(int position){
//额外的加密操作...
//额外的缓冲操作...
cout << endl << "加密!" << endl;
cout << "缓冲!" << endl;
FileStream::Seek(position);//定位文件流
//额外的加密操作...
//额外的缓冲操作...
}
virtual void Write(char data){
//额外的加密操作...
//额外的缓冲操作...
cout << endl << "加密!" << endl;
cout << "缓冲!" << endl;
FileStream::Write(data);//写文件流
//额外的加密操作...
//额外的缓冲操作...
}
};
/*网络和内存的加密+缓冲类似,略*/
可以想象,通过这种继承的方式,以后再扩展其他的功能,子类会多么臃肿。
需要解决的问题:
功能的扩展
”能够根据需要来动态地实现在上述例子的例子中,由于对FileStream NetworkStream MemoryStream
这3种流对read
操作的加密的方式完全一样,所以有很多相同的代码。可以做如下修改
read
。不用继承的方式,使用组合的方式:加一个父类指针数据成员Stream* stream
。read
方法,所以还是要继承Stream
类。这样,我们就可以将3个流FileStream NetworkStream MemoryStream
的加密扩展写成一个, 如下:
class CryptoStream : public Stream//为了overide需要扩展的方法
{
Stream* stream;//获得需要扩展的主体类:FileStream NetworkStream MemoryStream
public:
CryptoStream(Stream* _stream) :stream(_stream){}
virtual void Read(int number){
//加密:
cout << "加密" << endl;
stream->Read(number);
}
virtual void Seek(int position){
cout << "加密" << endl;
stream->Seek(position);
}
virtual void Write(char data){
cout << "加密" << endl;
stream->Write(data);
}
};
同理,缓冲如下:
class BufferedStream : public Stream//为了overide需要扩展的方法
{
Stream* stream;//获得需要扩展的主体类:FileStream NetworkStream MemoryStream
public:
BufferedStream(Stream* _stream) :stream(_stream){}
virtual void Read(int number){
//缓冲:
cout << "缓冲" << endl;
stream->Read(number);
}
virtual void Seek(int position){
cout << "缓冲" << endl;
stream->Seek(position);
}
virtual void Write(char data){
cout << "缓冲" << endl;
stream->Write(data);
}
};
完整的示例:
#include
using namespace std;
//业务操作
class Stream{
public:
virtual void Read(int number) = 0;
virtual void Seek(int position) = 0;
virtual void Write(char data) = 0;
virtual ~Stream(){}
};
//主体类
class FileStream : public Stream{
public:
virtual void Read(int number){
//读文件流
cout << "FileStream read" << endl;
}
virtual void Seek(int position){
//定位文件流
cout << "FileStream seak" << endl;
}
virtual void Write(char data){
//写文件流
cout << "FileStream write" << endl;
}
};
class NetworkStream :public Stream{
public:
virtual void Read(int number){
//读网络流
cout << "NetworkStream read" << endl;
}
virtual void Seek(int position){
//定位网络流
cout << "NetworkStream seak" << endl;
}
virtual void Write(char data){
//写网络流
cout << "NetworkStream write" << endl;
}
};
class MemoryStream :public Stream{
public:
virtual void Read(int number){
//读网络流
cout << "MemoryStream read" << endl;
}
virtual void Seek(int position){
//定位网络流
cout << "MemoryStream seak" << endl;
}
virtual void Write(char data){
//写网络流
cout << "MemoryStream write" << endl;
}
};
//加密扩展
class CryptoStream : public Stream//为了overide需要扩展的方法
{
Stream* stream;//获得需要扩展的主体类:FileStream NetworkStream MemoryStream
public:
CryptoStream(Stream* _stream) :stream(_stream){}
virtual void Read(int number){
//加密:
cout << "加密" << endl;
stream->Read(number);
}
virtual void Seek(int position){
cout << "加密" << endl;
stream->Seek(position);
}
virtual void Write(char data){
cout << "加密" << endl;
stream->Write(data);
}
};
//缓冲扩展
class BufferedStream : public Stream//为了overide需要扩展的方法
{
Stream* stream;//获得需要扩展的主体类:FileStream NetworkStream MemoryStream
public:
BufferedStream(Stream* _stream) :stream(_stream){}
virtual void Read(int number){
//缓冲:
cout << "缓冲" << endl;
stream->Read(number);
}
virtual void Seek(int position){
cout << "缓冲" << endl;
stream->Seek(position);
}
virtual void Write(char data){
cout << "缓冲" << endl;
stream->Write(data);
}
};
int main()
{
//文件流read
FileStream *fs1 = new FileStream;
fs1->Read(10);
//文件流read+加密
CryptoStream* crp = new CryptoStream(fs1);
crp->Read(10);
//文件流read+缓冲
BufferedStream* bs = new BufferedStream(fs1);
bs->Read(10);
//文件流read+缓冲+加密
BufferedStream* bs2 = new BufferedStream(crp);
bs2->Read(10);
system("pause");
return 0;
}
在上述例子中,其实也可以把BufferedStream CryptoStream
相同的数据成员Stream* stream
提出来,如下,添加一个DecoratorStream
类
class DecoratorStream : public Stream//为了overide需要扩展的方法
{
protected:
Stream* stream;//获得需要扩展的主体类:FileStream NetworkStream MemoryStream
DecoratorStream(Stream* _stream) :stream(_stream){}
};
//加密扩展
class CryptoStream : public DecoratorStream
{
public:
CryptoStream(Stream* _stream) :DecoratorStream(_stream){}
virtual void Read(int number){
//加密:
cout << "加密" << endl;
stream->Read(number);
}
virtual void Seek(int position){
cout << "加密" << endl;
stream->Seek(position);
}
virtual void Write(char data){
cout << "加密" << endl;
stream->Write(data);
}
};
//缓冲扩展
class BufferedStream : public DecoratorStream
{
public:
BufferedStream(Stream* _stream) :DecoratorStream(_stream){}
virtual void Read(int number){
//缓冲:
cout << "缓冲" << endl;
stream->Read(number);
}
virtual void Seek(int position){
cout << "缓冲" << endl;
stream->Seek(position);
}
virtual void Write(char data){
cout << "缓冲" << endl;
stream->Write(data);
}
};
BufferedStream CryptoStream
注:这里的ConcretreDecoratorA
和ConcretreDecoratorB
的addedState()
和AddedBehavier()
就是扩展功能的函数,比如例子中的加密或缓冲就可以写在这个成员函数里面。
stream->Read(number)
,在编译时,你无法确定是调用FileStream
还是NetworkStream
还是MemoryStream
的read
)的能力,而且可以根据需要扩展多个功能。避免了使用继承带来的“灵活性差”和“多子类衍生问题”。Stream
类,又有数据成员Stream* stream
)read
操作扩展加密操作)——是为“装饰”的含义。