設計模式(六)——單一職責模式-Bridge

對象模式所屬類別簡介-單一職責模式

單一職責模式包括:decorator裝飾者模式和Bridge橋接模式,用於解決責任不明確,使用繼承得到的結果往往隨着需求變化,子類數量過大。

當前模式簡介動機-Bridge

Bridge-橋接模式

需求

寫一個簡單PC平臺和移動平臺的發送消息的程序,這個程序要有登錄、發送信息、發送圖片的功能。PC平臺和移動平臺又分爲精簡版和完整版,完整版在每個動作之前都有音效動作 。

設計一


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

class IMessage
{
public:
	virtual ~IMessage(){};
	virtual void SendMsg() {};
	virtual void SendPic() {};
	virtual void Login() {};

	virtual void Connect() = 0;
	virtual void WriteText() = 0;
	virtual void WritePic() = 0;
	virtual void PlaySound() = 0;
};

class CPCMessge:public IMessage
{
public:
	virtual void WritePic() { std::cout << "CPCMessge WritePic" << std::endl;}
	virtual void WriteText() { std::cout << "CPCMessge WriteText" << std::endl;}
	virtual void Connect()   { std::cout << "CPCMessge Connect" << std::endl;}
	virtual void PlaySound()   { std::cout << "CPCMessge PlaySound" << std::endl;}
};

class CMobileCMessge:public IMessage
{
public:
	virtual void WritePic() { std::cout << "CMobile WritePic" << std::endl;}
	virtual void WriteText() { std::cout << "CMobile WriteText" << std::endl;}
	virtual void Connect()   { std::cout << "CMobile Connect" << std::endl;}
	virtual void PlaySound()   { std::cout << "CMobile PlaySound" << std::endl;}
};

class CPCMessgeLite : public CPCMessge
{
public:
	virtual void SendMsg() { CPCMessge::WriteText(); }
	virtual void SendPic() { CPCMessge::WritePic(); }
	virtual void Login()   { CPCMessge::Connect(); }
};

class CPCMessgePerfect: public CPCMessge
{
public:
	virtual void SendMsg() { CPCMessge::PlaySound(); CPCMessge::WriteText(); }
	virtual void SendPic() { CPCMessge::PlaySound(); CPCMessge::WritePic(); }
	virtual void Login()   { CPCMessge::PlaySound(); CPCMessge::Connect(); }
};

class CMobileCMessgeLite : public CMobileCMessge
{
public:
	virtual void SendMsg() { CMobileCMessge::WriteText(); }
	virtual void SendPic() { CMobileCMessge::WritePic(); }
	virtual void Login()   { CMobileCMessge::Connect(); }
};

class CMobileCMessgePerfect: public CMobileCMessge
{
public:
	virtual void SendMsg() { CMobileCMessge::PlaySound(); CMobileCMessge::WriteText(); }
	virtual void SendPic() { CMobileCMessge::PlaySound(); CMobileCMessge::WritePic(); }
	virtual void Login()   { CMobileCMessge::PlaySound(); CMobileCMessge::Connect(); }
};

int main() //調用
{
	IMessage *msg = new CMobileCMessgePerfect;
	msg->SendMsg();

	return 0;
}
//打印
CMobile PlaySound
CMobile WriteText

需求更改

設計一更改版本

違反原則

1.違反重構d 編譯時依賴-》運行時依賴,大量CMobileCMessge::PlaySound()靜態綁定。
2.違反設計模式5接口隔離原則,不用到的虛函數不必繼承。
virtual void SendMsg() {};
virtual void SendPic() {};
virtual void Login() {};
這三個在繼承上CPCMessge不需要,再下層CPCMessgeLite才需要

3.IMessage-CPCMessge-CPCMessgeLite兩次繼承,違反了設計模式6.優先使用對象組合而不是類繼承

設計二

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

class IMessage //業務
{
public:
	virtual ~IMessage(){};
	virtual void Connect() = 0;
	virtual void WriteText() = 0;
	virtual void WritePic() = 0;
	virtual void PlaySound() = 0;
};

class IMessagerImp //平臺
{
public:
	IMessage *m_p;
	virtual void SendMsg() = 0;
	virtual void SendPic() = 0;
	virtual void Login() = 0;
};

class CPCMessge:public IMessage
{
public:
	virtual void WritePic() { std::cout << "CPCMessge WritePic" << std::endl;}
	virtual void WriteText() { std::cout << "CPCMessge WriteText" << std::endl;}
	virtual void Connect()   { std::cout << "CPCMessge Connect" << std::endl;}
	virtual void PlaySound()   { std::cout << "CPCMessge PlaySound" << std::endl;}
};

class CMobileCMessge:public IMessage
{
public:
	virtual void WritePic() { std::cout << "CMobile WritePic" << std::endl;}
	virtual void WriteText() { std::cout << "CMobile WriteText" << std::endl;}
	virtual void Connect()   { std::cout << "CMobile Connect" << std::endl;}
	virtual void PlaySound()   { std::cout << "CMobile PlaySound" << std::endl;}
};

class CPCMessgeLite:public IMessagerImp
{
public:
	CPCMessgeLite(CPCMessge *p) { this->m_p = p;} //無法直接:m_p(p),因爲m_p是繼承的
	virtual void SendMsg() { m_p->WriteText(); }
	virtual void SendPic() { m_p->WritePic(); }
	virtual void Login()   { m_p->Connect(); }
};

class CPCMessgePerfect:public IMessagerImp
{
public:
	CPCMessgePerfect(CPCMessge *p) { this->m_p = p;}
	virtual void SendMsg() { m_p->PlaySound(); m_p->WriteText(); }
	virtual void SendPic() { m_p->PlaySound(); m_p->WritePic(); }
	virtual void Login()   { m_p->PlaySound(); m_p->Connect(); }
};

class CMobileCMessgeLite:public IMessagerImp
{
public:
	CMobileCMessgeLite(CMobileCMessge *p) { this->m_p = p;}
	virtual void SendMsg() { m_p->WriteText(); }
	virtual void SendPic() { m_p->WritePic(); }
	virtual void Login()   { m_p->Connect(); }
};

class CMobileCMessgePerfect:public IMessagerImp
{
public:
	CMobileCMessgePerfect(CMobileCMessge *p) { this->m_p = p;}
	virtual void SendMsg() { m_p->PlaySound(); m_p->WriteText(); }
	virtual void SendPic() { m_p->PlaySound(); m_p->WritePic(); }
	virtual void Login()   { m_p->PlaySound(); m_p->Connect(); }
};

int main() //調用
{
	IMessage *msg = new CMobileCMessge();
	IMessagerImp *msgImp = new CMobileCMessgePerfect((CMobileCMessge*)msg); //(CMobileCMessge*)m 需要顯示轉換一下
	msgImp->SendMsg();

	return 0;
}
//打印
CMobile PlaySound
CMobile WriteText

設計二更改版本

設計二比設計一區別

模式定義

將抽象部分(業務功能)與實現部分(平臺實現)分離,使它們都可以獨立地變化。

模式結構

在這裏插入圖片描述

要點總結

1.一個維度是業務,一個維度是平臺,平臺調用業務。先有平臺後有業務,兩個方向不互相影響。(比如IMessageimp依賴Imessage,PCMessageLite調用PCMessage),各個維度都只做自己的事情。

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