設計模式(五)——單一職責模式-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是一個產品,擁有這個元素或者繼承他的是他的組件)

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