前言:最近在看面向對象程序設計時,遇到了幾個新鮮的設計模式於是查了查資料,最終把他搞明白了,還是很開心的。。。
橋接模式
橋接模式的定義是這樣的:
1、GOF四人幫在《設計模式:可複用面向對象軟件的基礎》一書中是這樣描述的(見下引用),現在聽起來感覺雲裏霧裏的,不要在這裏糾結,我們接着往下。
將抽象部分和它的實現部分分離,使它們都可以獨立的變化。簡單粗暴的說,就是抽象對外提供調用的接口;對外隱瞞實現部分,在抽象中引用實現部分,從而實現抽象對實現部分的調用,而抽象中引用的實現部分可以在今後的開發過程中,切換成別的實現部分(《設計模式:可複用面向對象軟件的基礎》)
2、《大話設計模式》一書中是這樣描述的(見下引用)
將抽象部分與他的實現部分分離,使他們都可以獨立的變化(《大話設計模式》)
UML類圖
實例
1、繪製紅色的長方形、白色的圓形(Jelly Young:C++設計模式——橋接模式)
/*
** FileName : BridgePatternDemo
** Author : Jelly Young
** Date : 2013/12/4
** Description : More information (http://www.jellythink.com/)
** Author : Aidan Dai
** Date : 2015/11/20
** Description : 添加註釋(http://www.jellythink.com/archives/132)
*/
#include <iostream>
using namespace std;
/*
** 實現(顏料)
*/
class Implementor
{
public:
virtual void OperationImpl() = 0;
};
/*
** 具體實現(黃色顏料、綠色顏料、藍色顏料)
*/
class ConcreteImpementor : public Implementor
{
public:
void OperationImpl()
{
cout << "OperationImpl" << endl;
}
};
/*
** 抽象(平面圖形)
** 維護一個指向具體實現的指針(黃色顏料、綠色顏料、藍色顏料)
*/
class Abstraction
{
public:
Abstraction(Implementor *pImpl) : m_pImpl(pImpl){}
virtual void Operation() = 0;
protected:
Implementor *m_pImpl;
};
/*
** 被提煉的抽象(圓形、正方形、長方形)
*/
class RedfinedAbstraction : public Abstraction
{
public:
RedfinedAbstraction(Implementor *pImpl) : Abstraction(pImpl){}
void Operation()
{
m_pImpl->OperationImpl();
}
};
int main(void)
{
Implementor *pImplObj = new ConcreteImpementor();
Abstraction *pAbsObj = new RedfinedAbstraction(pImplObj);
pAbsObj->Operation();
delete pImplObj;
pImplObj = NULL;
delete pAbsObj;
pAbsObj = NULL;
return 0;
}
2、手機軟件何時統一(《大話設計模式》)
#include <iostream>
#include <string>
using namespace std;
class Implementor{
public:
void virtual Operation() = 0;
};
class ConcreteImplementorA : public Implementor{
public:
void Operation(){
cout << "ConcreteImplementorA" << endl;
}
};
class ConcreteImplementorB : public Implementor{
public:
void Operation(){
cout << "ConcreteImplementorB" << endl;
}
};
class Abstraction{
public:
void SetImplementor(Implementor *implementor){
this->m_implementor = implementor;
}
void virtual Operator() = 0;
protected:
Implementor *m_implementor;
};
class RefinedAbstraction : public Abstraction{
public:
void Operator(){
this->m_implementor->Operation();
}
};
int main(void){
Abstraction *abstraction = new RefinedAbstraction();
Implementor *implementor1 = new ConcreteImplementorA();
abstraction->SetImplementor(implementor1);
abstraction->Operator();
Implementor *implementor2 = new ConcreteImplementorB();
abstraction->SetImplementor(implementor2);
abstraction->Operator();
delete abstraction;
abstraction = NULL;
delete implementor1;
implementor1 = NULL;
delete implementor2;
implementor2 = NULL;
return 0;
}
3、自由切換家用電器開關(我給媳婦解釋設計模式:第一部分(譯文))
#include <iostream>
#include <string>
using namespace std;
class Equipment{
public:
void virtual poweron(string switchName) = 0;
void virtual poweroff(string switchName) = 0;
};
class Fan :public Equipment{
public:
void poweron(string switchName){
cout << "poweron Fan by " << switchName << endl;
}
void poweroff(string switchName){
cout << "poweroff Fan by " << switchName << endl;
}
};
class Light :public Equipment{
public:
void poweron(string switchName){
cout << "poweron Light by " << switchName << endl;
}
void poweroff(string switchName){
cout << "poweroff Light by " << switchName << endl;
}
};
class Switch{
public:
Switch(Equipment *equipment){
this->m_equipment = equipment;
}
void virtual on() = 0;
void virtual off() = 0;
Equipment *m_equipment;
};
class NormalSwitch :public Switch{
public:
NormalSwitch(Equipment *equipment) :Switch(equipment){
this->m_switchName = "NormalSwitch";
}
void on(){
this->m_equipment->poweron(this->m_switchName);
}
void off(){
this->m_equipment->poweroff(this->m_switchName);
}
private:
string m_switchName;
};
class FancySwitch :public Switch{
public:
FancySwitch(Equipment *equipment) :Switch(equipment){
this->m_switchName = "FancySwitch";
}
void on(){
this->m_equipment->poweron(this->m_switchName);
}
void off(){
this->m_equipment->poweroff(this->m_switchName);
}
private:
string m_switchName;
};
int main(void){
Equipment *equipment1 = new Fan();
Equipment *equipment2 = new Light();
Switch *equipmentSwitch1 = new NormalSwitch(equipment1);
Switch *equipmentSwitch2 = new FancySwitch(equipment2);
Switch *equipmentSwitch3 = new NormalSwitch(equipment1);
Switch *equipmentSwitch4 = new FancySwitch(equipment2);
equipmentSwitch1->on();
equipmentSwitch1->off();
equipmentSwitch2->on();
equipmentSwitch2->off();
equipmentSwitch3->on();
equipmentSwitch3->off();
equipmentSwitch4->on();
equipmentSwitch4->off();
delete equipment1;
equipment1 = NULL;
delete equipment2;
equipment2 = NULL;
delete equipmentSwitch1;
delete equipmentSwitch2;
delete equipmentSwitch3;
delete equipmentSwitch4;
equipmentSwitch1 = NULL;
equipmentSwitch2 = NULL;
equipmentSwitch3 = NULL;
equipmentSwitch4 = NULL;
return 0;
}
總結
is a 和 has a
1、理解繼承:
- 對象的繼承關係是在編譯時就定義好了,所以無法再無法再運行時改變從父類繼承的實現。子類的實現與它的父類有非常緊密的的依賴關係,以至於父類的實現中的任何變化必然會導致子類發生變化。當你需要複用子類時,如果繼承下來的實現不適合解決新的問題,則父類必須重寫或被其他更適合的類替換。這種依賴關係限制了靈活性並最終限制了複用性。
2、理解合成/聚合複用原則
- 合成/聚合複用原則:聚合表示一種弱的“擁有”關係,體現的是A對象可以包含B對象,但B對象不是A對象的一部分;合成則是一種強的“擁有”關係,體現了嚴格的部分和整體的關係,部分和整體的生命週期是一樣的[DRE]。
就像大雁、翅膀和雁羣的關係:
3、降低代碼耦合度
4、通過實例不斷的運用
結束語:
夢想還是要有的,萬一實現了了呢!