c++ 橋接模式
作用:將抽象部份與它的實現部份分離,使它們都可以獨立地變化。
將抽象(Abstraction)與實現(Implementation)分離,使得二者可以獨立地變化。
橋接模式號稱設計模式中最難理解的模式之一,關鍵就是這個抽象和實現的分離非常讓人奇怪,大部分人剛看到這個定義的時候都會認為實現就是繼承自抽象,那怎麼可能將他們分離呢。
《大話設計模式》中就Bridge模式的解釋:
手機品牌和軟體是兩個概念,不同的軟體可以在不同的手機上,不同的手機可以有相同的軟體,兩者都具有很大的變動性。如果我們單獨以手機品牌或手機軟體為基類來進行繼承擴充套件的話,無疑會使類的數目劇增並且耦合性很高,(如果更改品牌或增加軟體都會增加很多的變動)兩種方式的結構如下:
所以將兩者抽象出來兩個基類分別是PhoneBrand和PhoneSoft,那麼在品牌類中聚合一個軟體物件的基類將解決軟體和手機擴充套件混亂的問題,這樣兩者的擴充套件就相對靈活,剪短了兩者的必要聯絡,結構圖如下:
這樣擴充套件品牌和軟體就相對靈活獨立,達到解耦的目的!
UML結構圖如下:
抽象基類及介面:
1、Abstraction::Operation():定義要實現的操作介面
2、AbstractionImplement::Operation():實現抽象類Abstaction所定義操作的介面,由其具體派生類ConcreteImplemenA、ConcreteImplemenA或者其他派生類實現。
3、在Abstraction::Operation()中根據不同的指標多型呼叫AbstractionImplement::Operation()函式。
理解: Bridge用於將表示和實現解耦,兩者可以獨立的變化.在Abstraction類中維護一個AbstractionImplement類指標,需要採用不同的實現方式的時候只需要傳入不同的AbstractionImplement派生類就可以了.
Bridge的實現方式其實和Builde十分的相近,可以這麼說:本質上是一樣的,只是封裝的東西不一樣罷了.兩者的實現都有如下的共同點:
抽象出來一個基類,這個基類裡面定義了共有的一些行為,形成介面函式(對介面程式設計而不是對實現程式設計),這個介面函式在Buildier中是BuildePart函式在Bridge中是Operation函式;
其次,聚合一個基類的指標,如Builder模式中Director類聚合了一個Builder基類的指標,而Brige模式中Abstraction類聚合了一個AbstractionImplement基類的指標(優先採用聚合而不是繼承);
而在使用的時候,都把對這個類的使用封裝在一個函式中,在Bridge中是封裝在Director::Construct函式中,因為裝配不同部分的過程是一致的,而在Bridge模式中則是封裝在Abstraction::Operation函式中,在這個函式中呼叫對應的AbstractionImplement::Operation函式.就兩個模式而言,Builder封裝了不同的生成組成部分的方式,而Bridge封裝了不同的實現方式.
橋接模式就將實現與抽象分離開來,使得RefinedAbstraction依賴於抽象的實現,這樣實現了依賴倒轉原則,而不管左邊的抽象如何變化,只要實現方法不變,右邊的具體實現就不需要修改,而右邊的具體實現方法發生變化,只要介面不變,左邊的抽象也不需要修改。
常用的場景 1.當一個物件有多個變化因素的時候,考慮依賴於抽象的實現,而不是具體的實現。如上面例子中手機品牌有2種變化因素,一個是品牌,一個是功能。
2.當多個變化因素在多個物件間共享時,考慮將這部分變化的部分抽象出來再聚合/合成進來,如上面例子中的通訊錄和遊戲,其實是可以共享的。
3.當我們考慮一個物件的多個變化因素可以動態變化的時候,考慮使用橋接模式,如上面例子中的手機品牌是變化的,手機的功能也是變化的,所以將他們分離出來,獨立的變化。
優點 1.將實現抽離出來,再實現抽象,使得物件的具體實現依賴於抽象,滿足了依賴倒轉原則。
2.將可以共享的變化部分,抽離出來,減少了程式碼的重複資訊。
3.物件的具體實現可以更加靈活,可以滿足多個因素變化的要求。
缺點 1.客戶必須知道選擇哪一種型別的實現。
設計中有超過一維的變化我們就可以用橋模式。如果只有一維在變化,那麼我們用繼承就可以圓滿的解決問題。
程式碼如下:
#ifndef _ABSTRACTION_H_
#define _ABSTRACTION_H_
class AbstractionImplement;
class Abstraction
{
public:
virtual void Operation()=0;//定義介面,表示該類所支援的操作
virtual ~Abstraction();
protected:
Abstraction();
};
class RefinedAbstractionA:public Abstraction
{
public:
RefinedAbstractionA(AbstractionImplement* imp);//建構函式
virtual void Operation();//實現介面
virtual ~RefinedAbstractionA();//解構函式
private:
AbstractionImplement* _imp;//私有成員
};
class RefinedAbstractionB:public Abstraction
{
public:
RefinedAbstractionB(AbstractionImplement* imp);//建構函式
virtual void Operation();//實現介面
virtual ~RefinedAbstractionB();//解構函式
private:
AbstractionImplement* _imp;//私有成員
};
#endif
#include "Abstraction.h"
#include "AbstractionImplement.h"
#include <iostream>
using namespace std;
Abstraction::Abstraction()
{}
Abstraction::~Abstraction()
{}
RefinedAbstractionA::RefinedAbstractionA(AbstractionImplement* imp)
{
this->_imp = imp;
}
RefinedAbstractionA::~RefinedAbstractionA()
{
delete this->_imp;
this->_imp = NULL;
}
void RefinedAbstractionA::Operation()
{
cout << "RefinedAbstractionA::Operation" << endl;
this->_imp->Operation();
}
RefinedAbstractionB::RefinedAbstractionB(AbstractionImplement* imp)
{
this->_imp = imp;
}
RefinedAbstractionB::~RefinedAbstractionB()
{
delete this->_imp;
this->_imp = NULL;
}
void RefinedAbstractionB::Operation()
{
cout << "RefinedAbstractionB::Operation" << endl;
this->_imp->Operation();
}
#ifndef _ABSTRACTIONIMPLEMENT_H_
#define _ABSTRACTIONIMPLEMENT_H_
//抽象基類,定義了實現的介面
class AbstractionImplement
{
public:
virtual void Operation()=0;//定義操作介面
virtual ~AbstractionImplement();
protected:
AbstractionImplement();
};
// 繼承自AbstractionImplement,是AbstractionImplement的不同實現之一
class ConcreteAbstractionImplementA:public AbstractionImplement
{
public:
ConcreteAbstractionImplementA();
void Operation();//實現操作
~ConcreteAbstractionImplementA();
protected:
};
// 繼承自AbstractionImplement,是AbstractionImplement的不同實現之一
class ConcreteAbstractionImplementB:public AbstractionImplement
{
public:
ConcreteAbstractionImplementB();
void Operation();//實現操作
~ConcreteAbstractionImplementB();
protected:
};
#endif
#include "AbstractionImplement.h"
#include <iostream>
using namespace std;
AbstractionImplement::AbstractionImplement()
{}
AbstractionImplement::~AbstractionImplement()
{}
ConcreteAbstractionImplementA::ConcreteAbstractionImplementA()
{}
ConcreteAbstractionImplementA::~ConcreteAbstractionImplementA()
{}
void ConcreteAbstractionImplementA::Operation()
{
cout << "ConcreteAbstractionImplementA Operation" << endl;
}
ConcreteAbstractionImplementB::ConcreteAbstractionImplementB()
{}
ConcreteAbstractionImplementB::~ConcreteAbstractionImplementB()
{}
void ConcreteAbstractionImplementB::Operation()
{
cout << "ConcreteAbstractionImplementB Operation" << endl;
}
#include "Abstraction.h"
#include "AbstractionImplement.h"
#include <iostream>
using namespace std;
int main()
{
/* 將抽象部分與它的實現部分分離,使得它們可以獨立地變化
1、抽象Abstraction與實現AbstractionImplement分離;
2、抽象部分Abstraction可以變化,如new RefinedAbstractionA(imp)、new RefinedAbstractionB(imp2);
3、實現部分AbstractionImplement也可以變化,如new ConcreteAbstractionImplementA()、new ConcreteAbstractionImplementB();
*/
AbstractionImplement* imp = new ConcreteAbstractionImplementA(); //實現部分ConcreteAbstractionImplementA
Abstraction* abs = new RefinedAbstractionA(imp); //抽象部分RefinedAbstractionA
abs->Operation();
cout << "-----------------------------------------" << endl;
AbstractionImplement* imp1 = new ConcreteAbstractionImplementB(); //實現部分ConcreteAbstractionImplementB
Abstraction* abs1 = new RefinedAbstractionA(imp1); //抽象部分RefinedAbstractionA
abs1->Operation();
cout << "-----------------------------------------" << endl;
AbstractionImplement* imp2 = new ConcreteAbstractionImplementA(); //實現部分ConcreteAbstractionImplementA
Abstraction* abs2 = new RefinedAbstractionB(imp2); //抽象部分RefinedAbstractionB
abs2->Operation();
cout << "-----------------------------------------" << endl;
AbstractionImplement* imp3 = new ConcreteAbstractionImplementB(); //實現部分ConcreteAbstractionImplementB
Abstraction* abs3 = new RefinedAbstractionB(imp3); //抽象部分RefinedAbstractionB
abs3->Operation();
cout << endl;
return 0;
}