C++设计者模式——装饰模式

背景:在软件开发,如果责任划分的不清楚,是继承得到随着需求的变化子类会急剧膨胀,同时充斥着重复的代码这时候关键是需要划清责任

动机:在某些情况下我们可能过度的使用继承来扩展对象的功能,由于继承为类型引用的静态特性,是的这种扩展缺乏灵活性;并且随着子类的加多,各个子类的组合会导致更多子类的膨胀;

问题:如何是的对象的功能扩展能根据需求动态的实现呢?同时避免“扩展的功能增多”子类个数膨胀呢?从而使“功能扩展”带来的影响最小呢?

如下列子是对流的炒作,有文件流和网络流牟其中文件流还有加密文件流,缓存文件流,加密缓存文件流,网络流也有加密文件流,缓存网络流,加密缓存网络流;因为错误的使用继承,在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';
	}

};
//测试一下

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值