设计模式(五)——单一职责模式-Decorator模式

对象模式所属类别简介-单一职责模式

单一职责模式包括:decorator装饰者模式和Bridge桥接模式,用于解决责任不明确,使用继承得到的结果往往随着需求变化,子类数量过大。

当前模式简介动机-decorator

decorator-装饰者模式

需求

实现文件、内存、网络流的读、写、定位功能

设计一

#include "stdafx.h"
#include <iostream>
using namespace std;

class IStream
{
public:
	virtual ~IStream(){};
	virtual void read()=0;
	virtual void write()=0;
	virtual void seek()=0;
};
class CFileStream: public IStream
{
public:
	virtual void read() { std::cout << __FUNCTION__ << std::endl; }
	virtual void write() { std::cout << __FUNCTION__ << std::endl; }
	virtual void seek() { std::cout << __FUNCTION__ << std::endl; }
};

class CNetworkStream: public IStream
{
public:
	virtual void read() { std::cout << __FUNCTION__ << std::endl; }
	virtual void write() { std::cout << __FUNCTION__ << std::endl; }
	virtual void seek() { std::cout << __FUNCTION__ << std::endl; }
};

class CMemoryStream: public IStream
{
public:
	virtual void read() { std::cout << __FUNCTION__ << std::endl; }
	virtual void write() { std::cout << __FUNCTION__ << std::endl; }
	virtual void seek() { std::cout << __FUNCTION__ << std::endl; }
};

int main() //调用
{
	CMemoryStream *memory = new CMemoryStream;
	CNetworkStream *network = new CNetworkStream;
	CFileStream *file = new CFileStream;
	memory->read();
	network->read();
	file->read();
	//----------------
	IStream *test = new CMemoryStream;
	test->read();
	return 0;
}
//打印
CMemoryStream::read
CNetworkStream::read
CFileStream::read
CMemoryStream::read

需求更改

(实现文件、内存、网络流的读、写、定位功能)在读写定位功能上,添加加密和缓冲数据的步骤

设计一更改版本

#include "stdafx.h"
#include <iostream>
using namespace std;

class IStream
{
public:
	virtual ~IStream(){};
	virtual void read()=0;
	virtual void write()=0;
	virtual void seek()=0;
};
//////////////////////////////////////////////////
class CFileStream: public IStream
{
public:
	virtual void read() { std::cout << "CFileStream" << std::endl; }
	virtual void write() { std::cout << "CFileStream" << std::endl; }
	virtual void seek() { std::cout << "CFileStream" << std::endl; }
};

class CCryptoFileStream: public IStream
{
public:
	virtual void read() { std::cout << "Crypto" << std::endl; std::cout << "CFileStream" << std::endl; }
	virtual void write() { std::cout << "Crypto" << std::endl; std::cout << "CFileStream" << std::endl; }
	virtual void seek() { std::cout << "Crypto" << std::endl; std::cout << "CFileStream" << std::endl; }
};

class CCryptoBufferStream: public IStream
{
public:
	virtual void read() { std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CFileStream" << std::endl; }
	virtual void write() { std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CFileStream" << std::endl; }
	virtual void seek() { std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CFileStream" << std::endl; }
};
//////////////////////////////////////////////////
class CNetworkStream: public IStream
{
public:
	virtual void read() { std::cout << "CNetworkStream" << std::endl; }
	virtual void write() { std::cout << "CNetworkStream" << std::endl; }
	virtual void seek() { std::cout << "CNetworkStream" << std::endl; }
};

class CCryptoNetworkStream: public IStream
{
public:
	virtual void read() { std::cout << "Crypto" << std::endl; std::cout << "CNetworkStream" << std::endl; }
	virtual void write() { std::cout << "Crypto" << std::endl; std::cout << "CNetworkStream" << std::endl; }
	virtual void seek() { std::cout << "Crypto" << std::endl; std::cout << "CNetworkStream" << std::endl; }
};

class CCryptoBufferNetworkStream: public IStream
{
public:
	virtual void read() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CNetworkStream" << std::endl; }
	virtual void write() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CNetworkStream" << std::endl; }
	virtual void seek() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CNetworkStream" << std::endl; }
};
//////////////////////////////////////////////////
class CMemoryStream: public IStream
{
public:
	virtual void read() { std::cout << "CMemoryStream" << std::endl; }
	virtual void write() { std::cout << "CMemoryStream" << std::endl; }
	virtual void seek() { std::cout << "CMemoryStream" << std::endl; }
};

class CCryptoMemoryStream: public IStream
{
public:
	virtual void read() { std::cout << "Crypto" << std::endl; std::cout << "CMemoryStream" << std::endl; }
	virtual void write() { std::cout << "Crypto" << std::endl; std::cout << "CMemoryStream" << std::endl; }
	virtual void seek() { std::cout << "Crypto" << std::endl; std::cout << "CMemoryStream" << std::endl; }
};

class CCryptoBufferMemoryStream: public IStream
{
public:
	virtual void read() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CMemoryStream" << std::endl; }
	virtual void write() { std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CMemoryStream" << std::endl; }
	virtual void seek() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CMemoryStream" << std::endl; }
};

int main() //调用
{
	CMemoryStream *memory1 = new CMemoryStream;
	CNetworkStream *network1 = new CNetworkStream;
	CFileStream *file1 = new CFileStream;
	CCryptoMemoryStream *memory2 = new CCryptoMemoryStream;
	CCryptoNetworkStream *network2 = new CCryptoNetworkStream;
	CCryptoFileStream *file2 = new CCryptoFileStream;
	memory1->read();
	network1->read();
	file1->read();
	memory2->read();
	network2->read();
	file2->read();
	//----------------
	IStream *test = new CMemoryStream;
	test->read();
	return 0;
}
//打印
CMemoryStream
CNetworkStream
CFileStream
Crypto
CMemoryStream
Crypto
CNetworkStream
Crypto
CFileStream
CMemoryStream

违反原则

1.违反原则6多使用组合而不是继承
2.违反重构c多使用组合而不是继承

设计二

设计二更改版本

设计二更改版本一

#include "stdafx.h"
#include <iostream>
using namespace std;

class IStream
{
public:
	virtual ~IStream(){};
	virtual void read()=0;
	virtual void write()=0;
	virtual void seek()=0;
};
//////////////////////////////////////////////////
class CFileStream: public IStream
{
public:
	virtual void read() { std::cout << "CFileStream" << std::endl; }
	virtual void write() { std::cout << "CFileStream" << std::endl; }
	virtual void seek() { std::cout << "CFileStream" << std::endl; }
};

class CCryptoStream :public IStream //修改处(把crypto当做一种职责)
{
	IStream *m_stream;
public:
	CCryptoStream(IStream *stream):m_stream(stream){}
	virtual void read() { std::cout << "Crypto" << std::endl; m_stream->read(); }
	virtual void write() { std::cout << "Crypto" << std::endl; m_stream->write(); }
	virtual void seek() { std::cout << "Crypto" << std::endl; m_stream->seek(); }
};

//继承父类,又包含父类,很可能都是这个模式(父类IStream)
class CBufferStream: public IStream
{
	IStream *m_stream;
public:
	CBufferStream(IStream *stream):m_stream(stream){}
	virtual void read() { std::cout << "Buffer" << std::endl; m_stream->read(); }
	virtual void write() { std::cout << "Buffer" << std::endl; m_stream->read(); }
	virtual void seek() { std::cout << "Buffer" << std::endl; m_stream->read(); }
};
//////////////////////////////////////////////////
class CNetworkStream: public IStream
{
public:
	virtual void read() { std::cout << "CNetworkStream" << std::endl; }
	virtual void write() { std::cout << "CNetworkStream" << std::endl; }
	virtual void seek() { std::cout << "CNetworkStream" << std::endl; }
};

class CCryptoBufferNetworkStream: public IStream
{
public:
	virtual void read() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CNetworkStream" << std::endl; }
	virtual void write() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CNetworkStream" << std::endl; }
	virtual void seek() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CNetworkStream" << std::endl; }
};
//////////////////////////////////////////////////
class CMemoryStream: public IStream
{
public:
	virtual void read() { std::cout << "CMemoryStream" << std::endl; }
	virtual void write() { std::cout << "CMemoryStream" << std::endl; }
	virtual void seek() { std::cout << "CMemoryStream" << std::endl; }
};

class CCryptoBufferMemoryStream: public IStream
{
public:
	virtual void read() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CMemoryStream" << std::endl; }
	virtual void write() { std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CMemoryStream" << std::endl; }
	virtual void seek() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CMemoryStream" << std::endl; }
};

int main() //调用
{
	CMemoryStream *memory1 = new CMemoryStream;
	CNetworkStream *network1 = new CNetworkStream;

	CFileStream *file1 = new CFileStream;
	CCryptoStream *memory2 = new CCryptoStream(memory1);
	CBufferStream *memory3 = new CBufferStream(memory2);

	memory1->read();
	network1->read();
	file1->read();

	memory2->read();
	memory3->read();

	//----------------
	IStream *test = new CMemoryStream;
	test->read();
	return 0;
}
//打印
CMemoryStream
CNetworkStream
CFileStream
Crypto
CMemoryStream
Buffer
Crypto
CMemoryStream
CMemoryStream

设计二更改版本二

设计二只能先加密后缓冲处理,位置无法自由组合

#include "stdafx.h"
#include <iostream>
using namespace std;

class IStream
{
public:
	virtual ~IStream(){};
	virtual void read()=0;
	virtual void write()=0;
	virtual void seek()=0;
};
//////////////////////////////////////////////////
class CFileStream: public IStream
{
public:
	virtual void read() { std::cout << "CFileStream" << std::endl; }
	virtual void write() { std::cout << "CFileStream" << std::endl; }
	virtual void seek() { std::cout << "CFileStream" << std::endl; }
};

class CNetworkStream: public IStream
{
public:
	virtual void read() { std::cout << "CNetworkStream" << std::endl; }
	virtual void write() { std::cout << "CNetworkStream" << std::endl; }
	virtual void seek() { std::cout << "CNetworkStream" << std::endl; }
};

class CCryptoBufferNetworkStream: public IStream
{
public:
	virtual void read() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CNetworkStream" << std::endl; }
	virtual void write() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CNetworkStream" << std::endl; }
	virtual void seek() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CNetworkStream" << std::endl; }
};
//////////////////////////////////////////////////
class CMemoryStream: public IStream
{
public:
	virtual void read() { std::cout << "CMemoryStream" << std::endl; }
	virtual void write() { std::cout << "CMemoryStream" << std::endl; }
	virtual void seek() { std::cout << "CMemoryStream" << std::endl; }
};

class CCryptoBufferMemoryStream: public IStream
{
public:
	virtual void read() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CMemoryStream" << std::endl; }
	virtual void write() { std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CMemoryStream" << std::endl; }
	virtual void seek() {  std::cout << "Crypto" << std::endl;  std::cout << "Buffer" << std::endl; std::cout << "CMemoryStream" << std::endl; }
};

class DecoratorStream: public IStream{
protected:
	IStream* m_stream;
	DecoratorStream(IStream * stm):m_stream(stm){

	}
};
class CCryptoStream :public DecoratorStream //修改处(把crypto当做一种职责)
{
public:
	CCryptoStream(IStream* stm):DecoratorStream(stm){}
	virtual void read() { std::cout << "Crypto" << std::endl; m_stream->read(); }
	virtual void write() { std::cout << "Crypto" << std::endl; m_stream->write(); }
	virtual void seek() { std::cout << "Crypto" << std::endl; m_stream->seek(); }
};

class CBufferStream: public DecoratorStream
{
public:
	CBufferStream(IStream* stm):DecoratorStream(stm){}
	virtual void read() { std::cout << "Buffer" << std::endl; m_stream->read(); }
	virtual void write() { std::cout << "Buffer" << std::endl; m_stream->read(); }
	virtual void seek() { std::cout << "Buffer" << std::endl; m_stream->read(); }
};

int main() //调用
{
	CMemoryStream *memory1 = new CMemoryStream;
	CNetworkStream *network1 = new CNetworkStream;

	CFileStream *file1 = new CFileStream;
	DecoratorStream *memory2 = new CCryptoStream(memory1);
	DecoratorStream *memory3 = new CBufferStream(memory2);

	memory1->read();
	network1->read();
	file1->read();

	memory2->read();
	memory3->read();

	//----------------
	IStream *test = new CMemoryStream;
	test->read();
	return 0;
}
//打印
CMemoryStream
CNetworkStream
CFileStream
Crypto
CMemoryStream
Buffer
Crypto
CMemoryStream
CMemoryStream

设计二比设计一区别

模式定义

动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 & 减少子类个数)

模式结构

在这里插入图片描述

要点总结

1、装饰模式是用来解决同一层面类似问题的扩展
2、装饰模式是上一个产品的组件,也是多个组件的产品(IStream是一个产品,拥有这个元素或者继承他的是他的组件)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章