当存在部分子类共有的成员,但直接提到基类又不必要的情况下。使用装饰模式将那部分共有成员独立出来成为装饰类,包含这些部分共有的成员,需要这些成员的继承自该装饰类,不需要的直接继承基类。
base.h
#pragma once
class IStream
{
public:
virtual void Read(int num) = 0;
virtual void Seek(int pos) = 0;
virtual void Write(char data) = 0;
virtual ~IStream(){}
};
imp.h
#pragma once
#include "base.h"
////////////////////////////////
class CFileStream:public IStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CFileStream(){}
};
class CNetStream:public IStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CNetStream(){}
};
class CMemStream:public IStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CMemStream(){}
};
#if 0
//////////////////////////////////////////
class CryptoFileStream:public CFileStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CryptoFileStream(){}
};
class CryptoNetStream:public CNetStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CryptoNetStream(){}
};
class CryptoMemStream:public CMemStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CryptoMemStream(){}
};
//////////////////////////////////////////
class CFileBufferStream:public CFileStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CFileBufferStream(){}
};
class CNetBufferStream:public CNetStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CNetBufferStream(){}
};
class CMemBufferStream:public CMemStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CMemBufferStream(){}
};
//////////////////////////////////////////
class CryptoFileBufferStream:public CFileStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CryptoFileBufferStream(){}
};
class CryptoNetBufferStream:public CFileStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CryptoNetBufferStream(){}
};
class CryptoMemBufferStream:public CFileStream
{
public:
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CryptoMemBufferStream(){}
};
#else
/*
1.通过将使用组合而非继承将stream实际类型在运行时确定,
达到在编译时CryptoStream,CBufferStream,CryptoBufferStream都是稳定的。
2.IStream使用组合后,理论上CryptoStream,CBufferStream,CryptoBufferStream
可以不再继承IStream,但是为接口规范,IStream定义子类接口标准,子类必须签名一致。
3.IStream本身是既被CFileStream等继承
又被CryptoStream,CBufferStream,CryptoBufferStream等继承
但是又不能直接提到IStream基类中,故使用装饰模式,创造一个中间类。
*/
class CDecoratorStream:public IStream
{
protected:
IStream* m_stream;
CDecoratorStream(IStream* stm):m_stream(stm){}
};
class CryptoStream:public CDecoratorStream
{
public:
CryptoStream(IStream* stm):CDecoratorStream(stm){}
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CryptoStream(){}
};
class CBufferStream:public CDecoratorStream
{
public:
CBufferStream(IStream* stm):CDecoratorStream(stm){}
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CBufferStream(){}
};
class CryptoBufferStream:public CDecoratorStream
{
public:
CryptoBufferStream(IStream* stm):CDecoratorStream(stm){}
virtual void Read(int num);
virtual void Seek(int pos);
virtual void Write(char data);
virtual ~CryptoBufferStream(){}
};
#endif
imp.cpp
#include <iostream>
#include "imp.h"
using namespace std;
void CFileStream::Read(int num)
{
cout << "CFileStream Read" << endl;
}
void CFileStream::Seek(int pos)
{
cout << "CFileStream Seek" << endl;
}
void CFileStream::Write(char data)
{
cout << "CFileStream Write" << endl;
}
void CNetStream::Read(int num)
{
cout << "CNetStream Read" << endl;
}
void CNetStream::Seek(int pos)
{
cout << "CNetStream Seek" << endl;
}
void CNetStream::Write(char data)
{
cout << "CNetStream Write" << endl;
}
void CMemStream::Read(int num)
{
cout << "CMemStream Read" << endl;
}
void CMemStream::Seek(int pos)
{
cout << "CMemStream Seek" << endl;
}
void CMemStream::Write(char data)
{
cout << "CMemStream Write" << endl;
}
///////////////////////////////////////////
void CryptoStream::Read(int num)
{
m_stream->Read(num);
cout << "CryptoStream Read" << endl;
}
void CryptoStream::Seek(int pos)
{
m_stream->Seek(pos);
cout << "CryptoStream Seek" << endl;
}
void CryptoStream::Write(char data)
{
m_stream->Write(data);
cout << "CryptoStream Write" << endl;
}
////////////////////////////////////////////
void CBufferStream::Read(int num)
{
m_stream->Read(num);
cout << "CBufferStream Read" << endl;
}
void CBufferStream::Seek(int pos)
{
m_stream->Seek(pos);
cout << "CBufferStream Seek" << endl;
}
void CBufferStream::Write(char data)
{
m_stream->Write(data);
cout << "CBufferStream Write" << endl;
}
/////////////////////////////////////////////
void CryptoBufferStream::Read(int num)
{
m_stream->Read(num);
cout << "CryptoBufferStream Read" << endl;
}
void CryptoBufferStream::Seek(int pos)
{
m_stream->Seek(pos);
cout << "CryptoBufferStream Seek" << endl;
}
void CryptoBufferStream::Write(char data)
{
m_stream->Write(data);
cout << "CryptoBufferStream Write" << endl;
}
main.cpp
#include "base.h"
#include "imp.h"
int main()
{
CFileStream fileStream;
CBufferStream bufStream(&fileStream);
bufStream.Read(5);
CNetStream netStream;
CryptoStream cryptoStream(&netStream);
cryptoStream.Seek(10);
CMemStream menStream;
CryptoBufferStream cryptoBufStream(&menStream);
cryptoBufStream.Write('x');
return 0;
}