結構型模式Structural Patterns之橋接模式bridge

@著作權歸作者所有:來自CSDN博客作者大鬍子的艾娃的原創作品,如需轉載,請註明出處https://blog.csdn.net/qq_43148810,否則將追究法律責任。
如有錯誤的地方歡迎指正,謝謝!

一、Messager 類設計的場景:
1、由於某些類型的固有的實現邏輯,使得它們具有兩個變化的維度, 乃至多個緯度的變化。
2、利用面向對象技術來使得類型可以輕鬆地沿着兩個乃至多個方向變化,而不引入額外的複雜度。
例如:Messager 類的方法有平臺實現{PlaySound,DrawShape,WriteText,Connect}和業務抽象{Login,SendMessage,SendPicture}

實現思路:將抽象部分(業務功能)與實現部分(平臺實現)分離,使它們都可以獨立地變化。
實現技術1:多繼承方案,抽象部分(業務功能)爲一個基類,實現部分(平臺實現)爲一個基類,不推薦,違背單一職責原則,複用性差。
實現技術2:單繼承一個的維度變化,其他維度的變化各自打包成一個基類,推薦使用。
備註:理解C++的繼承關係

#pragma once
#include<string>
struct Image
{
	Image()
	{
		date = new int[800*600];
	}
	~Image()
	{
		delete date;
	}
	int *date;
	int height;
	int width;
	int type;
};

class MessagerImp {
public:
	virtual void PlaySound() = 0;
	virtual void DrawShape() = 0;
	virtual void WriteText() = 0;
	virtual void Connect() = 0;
};

//平臺實現 n
class PCMessagerImp : public MessagerImp {
public:

	virtual void PlaySound() {
		//**********
	}
	virtual void DrawShape() {
		//**********
	}
	virtual void WriteText() {
		//**********
	}
	virtual void Connect() {
		//**********
	}
};

class MobileMessagerImp : public MessagerImp {
public:

	virtual void PlaySound() {
		//==========
	}
	virtual void DrawShape() {
		//==========
	}
	virtual void WriteText() {
		//==========
	}
	virtual void Connect() {
		//==========
	}
};


class Messager {
private:
	//**MessagerImp爲變化的一個維度,打包成虛基類,該類指針成爲一個成員對象,多維的話,再多幾個這樣的成員對象**
	MessagerImp* messagerImp;//...
public:
	virtual void Login(std::string username, std::string password) const = 0;
	virtual void SendMessage(std::string message) const = 0;
	virtual void SendPicture(Image image) const = 0;

	MessagerImp* getMessagerImp() const {
		return messagerImp;
	}
	Messager(MessagerImp* messagerImp) {
		this->messagerImp = messagerImp;
	}
	virtual ~Messager() {
	}
};

//業務抽象 m
//MessagerLite,MessagerPerfect根據不同需求的業務實現
//類的數目:1+n+m
class MessagerLite :public Messager {
public:

	virtual void Login(std::string username, std::string password) const override {

		getMessagerImp()->Connect();
		//........
	}
	virtual void SendMessage(std::string message)  const override {

		getMessagerImp()->WriteText();
		//........
	}
	virtual void SendPicture(Image image)  const override {

		getMessagerImp()->DrawShape();
		//........
	}

	MessagerLite(MessagerImp* messagerImp)
		:Messager(messagerImp){
	}
};


class MessagerPerfect :public Messager {
public:
	virtual void Login(std::string username, std::string password) const override {

		getMessagerImp()->PlaySound();
		//********
		getMessagerImp()->Connect();
		//........
	}
	virtual void SendMessage(std::string message) const override {

		getMessagerImp()->PlaySound();
		//********
		getMessagerImp()->WriteText();
		//........
	}
	virtual void SendPicture(Image image) const override {

		getMessagerImp()->PlaySound();
		//********
		getMessagerImp()->DrawShape();
		//........
	}

	MessagerPerfect(MessagerImp* messagerImp)
		:Messager(messagerImp){
	}
};

二、具體調用

#include"Bridge.h"
int main()
{
	//運行時裝配
	MessagerImp* mImp = new PCMessagerImp();	//或new MobileMessagerImp();
	Messager *mLite = new MessagerLite(mImp);
	Messager *mPerfect = new MessagerPerfect(mImp);

	mLite->Login(s, s);
	mLite->getMessagerImp()->Connect();
	mLite->getMessagerImp()->WriteText();
	
	delete mLite;
	delete mPerfect;
	delete mImp;
}

三:總結
1、Bridge模式使用“對象間的組合關係”解耦了抽象和實現之間固有的綁定關係,使得抽象和實現可以沿着各自的維度來變化。所謂抽象和實現沿着各自緯度的變化,即“子類化”它們。
2、Bridge模式有時候類似於多繼承方案,但是多繼承方案往往違背 單一職責原則(即一個類只有一個變化的原因),複用性比較差。 Bridge模式是比多繼承方案更好的解決方法。
3、Bridge模式的應用一般在“兩個非常強的變化維度”,有時一個類也有多於兩個的變化維度,這時可以使用Bridge的擴展模式。

更多內容請關注個人博客:https://blog.csdn.net/qq_43148810

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