设计模式第六讲--装饰模式 Decorator
1. “单一职责”模式
在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任。
典型模式
Decorator
Bridge
2. 动机(Motivation)
在某些情况下我们可能会“过度的使用继承来扩展对象的功能”,由于继承为类型引入的静态特质(没有变化的可能性),使得这种扩展方式缺乏灵活性;并且随着子类增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。
如何使“对象功能的扩展”能够根据需求来动态的实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响降为最低。
3.代码
//业务操作
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)
	{
		//读文件流
	}
	virtual void Seek(int position)
	{
		//定位文件流
	}
	virtual void Write(char data)
	{
		//写文件流
	}
};
class NetworkStream : public Stream
{
public:
	virtual char Read(int number)
	{
		//读网络流
	}
	virtual void Seek(int position)
	{
		//定位网络流
	}
	virtual void Write(char data)
	{
		//写网络流
	}
};
class MemoryStream :public Stream
{
public:
	virtual char Read(int number)
	{
		//读内存流
	}
	virtual void Seek(int position)
	{
		//定位内存流
	}
	virtual void Write(char data)
	{
		//写内存流
	}
};
//扩展操作
class CrytoFileStream :public FileStream
{
public:
	virtual char Read(int number)
	{
		//额外的加密操作。。。
		FileStream::Read(number);  //读文件流
	}
	virtual void Seek(int position)
	{
		//额外的加密操作。。。
		FileStream::Seek(position); //定位文件流
	}
	virtual void Write(char data)
	{
		//额外的加密操作。。。
		FileStream::Write(data);//写文件流
	}
};
//扩展操作
class CrytoNetworkStream :public NetworkStream
{
public:
	virtual char Read(int number)
	{
		//额外的加密操作。。。
		NetworkStream::Read(number);  //读网络流
	}
	virtual void Seek(int position)
	{
		//额外的加密操作。。。
		NetworkStream::Seek(position); //定位网络流
	}
	virtual void Write(char data)
	{
		//额外的加密操作。。。
		NetworkStream::Write(data);//写网络流
	}
};
//扩展操作
class CrytoMemoryStream :public MemoryStream
{
public:
	virtual char Read(int number)
	{
		//额外的加密操作。。。
		MemoryStream::Read(number);  //读内存流
	}
	virtual void Seek(int position)
	{
		//额外的加密操作。。。
		MemoryStream::Seek(position); //定位内存流
	}
	virtual void Write(char data)
	{
		//额外的加密操作。。。
		MemoryStream::Write(data);//写内存流
	}
};
class BufferdFileStream :public FileStream
{
	//...
};
class BufferedNetworkStream :public NetworkStream
{
	//...
};
class BufferedMemoryStream :public MemoryStream
{
	//...
};
class CryptoBufferedFileSream :public FileStream
{
public:
	virtual char Read(int number)
	{
		//额外的加密操作
		//额外的缓冲操作
		FileStream::Read(number);  //读文件流
	}
	virtual void Seek(int position)
	{
		//额外的加密操作
		//额外的缓冲操作
		FileStream::Seek(position); //定位文件流
	}
	virtual void Write(char data)
	{
		//额外的加密操作
		//额外的缓冲操作
		FileStream::Write(data);//写文件流
	}
};
void Process()
{
	//编译时装配
	CrytoFileStream* fs1 = new CrytoFileStream();
	BufferdFileStream* fs2 = new BufferdFileStream();
	CryptoBufferedFileSream* fs3 = new CryptoBufferedFileSream();
}
类之间的继承关系如下图所示:

采用Decorator模式修改完成之后的代码如下:
//业务操作
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)
	{
		//读文件流
	}
	virtual void Seek(int position)
	{
		//定位文件流
	}
	virtual void Write(char data)
	{
		//写文件流
	}
};
class NetworkStream : public Stream
{
public:
	virtual char Read(int number)
	{
		//读网络流
	}
	virtual void Seek(int position)
	{
		//定位网络流
	}
	virtual void Write(char data)
	{
		//写网络流
	}
};
class MemoryStream :public Stream
{
public:
	virtual char Read(int number)
	{
		//读内存流
	}
	virtual void Seek(int position)
	{
		//定位内存流
	}
	virtual void Write(char data)
	{
		//写内存流
	}
};
class DecoratorStream :public Stream
{
protected:
	Stream* stream;              //...
	DecoratorStream(Stream* s) :stream(s)
	{};
};
//扩展操作
class CrytoStream :public DecoratorStream     //这个地方继承Stream只是为了遵循接口规范。
{
public:
	//构造器
	CrytoStream(Stream* s) :DecoratorStream(s)
	{
	}
	virtual char Read(int number)
	{
		//额外的加密操作。。。
		stream->Read(number);
	}
	virtual void Seek(int position)
	{
		//额外的加密操作。。。
		stream->Seek(position);
	}
	virtual void Write(char data)
	{
		//额外的加密操作。。。
		stream->Write(data);
	}
};
class BufferdStream :public DecoratorStream
{
public:
	BufferdStream(Stream* s) :DecoratorStream(s)
	{
	}
	virtual char Read(int number)
	{
		//额外的缓冲操作。。。
		stream->Read(number);
	}
	virtual void Seek(int position)
	{
		//额外的缓冲操作。。。
		stream->Seek(position);
	}
	virtual void Write(char data)
	{
		//额外的缓冲操作。。。
		stream->Write(data);
	}
};
void Process()
{
	//运行时装配
	FileStream* s1 = new FileStream();
	CrytoStream* s2 = new CrytoStream(s1);
	BufferdStream* s3 = new BufferdStream(s1);
	BufferdStream* s4 = new BufferdStream(s2);   //既加密又缓存
}
各类之间的继承关系图

4. 模式定义
动态(组合)的给一个对象增加一些额外的职责,就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码&减少子类个数)。
5. 结构
 
6. 要点总结
通过采用组合而非继承的手法,Decorator模式实现了在运动时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了使用继承带来的“灵活性差”和“多子类衍生问题”。
Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。
Decorator模式的目的并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。
posted on 2021-12-07 23:21 xcxfury001 阅读(36) 评论(0) 收藏 举报
 
                    
                     
                    
                 
                    
                 
                
            
         
 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号