日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++设计模式之桥接模式

發(fā)布時(shí)間:2024/4/11 c/c++ 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++设计模式之桥接模式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


這篇文章主要介紹了C++設(shè)計(jì)模式之橋接模式,本文講解了什么是橋接模式、為什么要使用橋接模式、什么時(shí)候使用橋接模式等內(nèi)容,需要的朋友可以參考下

問題描述

現(xiàn)在要去畫一個(gè)圖形,圖形有長方形、圓形和扇形等等;而圖形又可以加上不同的顏色,然后,我們就可以畫出紅色的長方形,綠色的長方形;紅色的圓形,綠色的圓形等等。而這種圖形的形狀在變化,圖形的顏色也在變化,當(dāng)使用代碼去實(shí)現(xiàn)時(shí),如何面對這種多方面的變化呢?這就要說到今天的橋接模式了。

什么是橋接模式?

對于上述的圖形與顏色的問題時(shí),很多時(shí)候,我們讓各個(gè)圖形類繼承顏色類,比如:

復(fù)制代碼代碼如下:
class CShape
{
};
class CRectangle : public CShape
{
};
class CCircle : public CShape
{
};
class CColor
{
};
class CRed : public CColor
{
};
class CBlue : public CColor
{
};
class CRedRectangle : public CRed
{
};
class CBlueRectangle : public CBlue
{
};

每當(dāng)我們增加一個(gè)新的圖形,或者增加一種新的顏色時(shí),對應(yīng)的類就會以相乘的速度進(jìn)行增加。當(dāng)系統(tǒng)中的類變的多時(shí),對應(yīng)的管理也就變的復(fù)雜,這不是我們希望看到的。同時(shí),我們可以看到CRedRectangle類繼承自CRed類,這種繼承關(guān)系合理嗎?且不說有的系統(tǒng)是如此實(shí)現(xiàn)的,紅色的矩形是紅色嗎?很顯然,CRedRectangle和CRed之間不是一種is-a的關(guān)系,所以,上面的實(shí)現(xiàn)是及其不合理的。那么它們是什么關(guān)系呢?接著往下看。

在GOF的《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書中對橋接模式是這樣說的:將抽象部分和它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立的變化。簡單粗暴的說,就是抽象對外提供調(diào)用的接口;對外隱瞞實(shí)現(xiàn)部分,在抽象中引用實(shí)現(xiàn)部分,從而實(shí)現(xiàn)抽象對實(shí)現(xiàn)部分的調(diào)用,而抽象中引用的實(shí)現(xiàn)部分可以在今后的開發(fā)過程中,切換成別的實(shí)現(xiàn)部分。

為什么要使用橋接模式?

當(dāng)一個(gè)抽象可能有多個(gè)實(shí)現(xiàn)時(shí),通常用繼承來協(xié)調(diào)它們。抽象類定義對該抽象的接口,而具體的子類則用不同方式加以實(shí)現(xiàn)。但是此方法有時(shí)不夠靈活。繼承機(jī)制將抽象部分與它的實(shí)現(xiàn)部分固定在一起,使得難以對抽象部分和實(shí)現(xiàn)部分獨(dú)立的進(jìn)行修改、擴(kuò)充和重用。橋接模式把依賴具體實(shí)現(xiàn),提升為依賴抽象,來完成對象和變化因素之間的低耦合,提高系統(tǒng)的可維護(hù)性和擴(kuò)展性。橋接模式的主要目的是將一個(gè)對象的變化與其它變化隔離開,讓彼此之間的耦合度最低。

什么時(shí)候使用橋接模式?

1.如果不希望在抽象和它的實(shí)現(xiàn)部分之間有一個(gè)固定的綁定關(guān)系,也就是繼承關(guān)系;如果我們打破了這種固定的綁定關(guān)系,以后,就可以方便的在抽象部分切換不同的實(shí)現(xiàn)部分;

2.如果希望類的抽象以及它的實(shí)現(xiàn)都應(yīng)該可以通過生成子類的方法加以擴(kuò)充;如果不使用橋接模式,使用繼承去實(shí)現(xiàn)時(shí),在抽象類中添加一個(gè)方法,則在對應(yīng)的實(shí)現(xiàn)類中也需要做對應(yīng)的改動,這種實(shí)現(xiàn)不符合松耦合的要求;

3.如果要求對一個(gè)抽象的實(shí)現(xiàn)部分的修改對客戶不產(chǎn)生影響,即客戶的代碼不需要重新編譯,在后面的項(xiàng)目經(jīng)驗(yàn)會說這方面;

4.如果想對客戶完全隱藏抽象的實(shí)現(xiàn)部分;

5.如果一個(gè)對象有多個(gè)變化因素的時(shí)候,通過抽象這些變化因素,將依賴具體實(shí)現(xiàn),修改為依賴抽象;

6.如果某個(gè)變化因素在多個(gè)對象中共享時(shí),可以抽象出這個(gè)變化因素,然后實(shí)現(xiàn)這些不同的變化因素。

上面使用的場景,是一種建議,也是一種參考。在項(xiàng)目中要很好的把握一個(gè)設(shè)計(jì)模式,是有一定的難度的;當(dāng)在實(shí)際項(xiàng)目中遇到滿足上面的一點(diǎn)或者幾點(diǎn)時(shí),可以考慮使用橋接模式。

UML類圖

Abstraction類定義了抽象類的接口,并且維護(hù)一個(gè)指向Implementor實(shí)現(xiàn)類的指針;

RefineAbstraction類擴(kuò)充了Abstraction類的接口;

Implementor類定義了實(shí)現(xiàn)類的接口,這個(gè)接口不一定要與Abstraction的接口完全一致;實(shí)際上,這兩個(gè)接口可以完全不同;

ConcreteImplementor類實(shí)現(xiàn)了Implementor定義的接口。

代碼實(shí)現(xiàn)

復(fù)制代碼代碼如下:
/*
** FileName???? : BridgePatternDemo
** Author?????? : Jelly Young
** Date???????? : 2013/12/4
** Description? : More information, please go to http://www.jb51.net
*/
#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(int argc, char *argv[])
{
???? Implementor *pImplObj = new ConcreteImpementor();
???? Abstraction *pAbsObj = new RedfinedAbstraction(pImplObj);
???? pAbsObj->Operation();
???? delete pImplObj;
???? pImplObj = NULL;
???? delete pAbsObj;
???? pAbsObj = NULL;
???? return 0;
}

根據(jù)對代碼的理解,能想象到CRedRectangle和CRed是什么關(guān)系嗎?我們可以理解為紅色的矩形包含紅色,也就是包含的關(guān)系,也就是軟件設(shè)計(jì)中的組合關(guān)系(has-a)。

項(xiàng)目經(jīng)驗(yàn)

這是一個(gè)我經(jīng)歷的項(xiàng)目,也是做起來比較輕松的一個(gè)項(xiàng)目。項(xiàng)目是這樣的,需要對一個(gè)中間的通信庫進(jìn)行改寫,保留以前的通信方式的同時(shí),需要使用一種新的通信協(xié)議去和底層模塊進(jìn)行通信。現(xiàn)有的代碼是一個(gè)COM程序,向外提供了可以調(diào)用的接口。根據(jù)客戶提供的源碼,我們進(jìn)行了分析;在分析之前,我們有一種擔(dān)心,就是怕用戶的代碼是接口和實(shí)現(xiàn)混在一起的;但是,分析之后,讓我們很吃驚,客戶的代碼結(jié)構(gòu)很清晰,層次非常清楚,代碼中使用的就是我們今天這里說的橋接模式。由于抽象的接口和實(shí)現(xiàn)完全進(jìn)行了分離,我們在進(jìn)行重寫時(shí),只需要實(shí)現(xiàn)我們的一個(gè)類,然后在接口中引用我們實(shí)現(xiàn)的類,就大功告成了,這樣做到了客戶端不需要做任何修改,就可以完美的替換掉原來的通信層,真的是前人栽樹樹,后人乘涼啊。

總結(jié)

橋接模式使得抽象和實(shí)現(xiàn)進(jìn)行了分離,抽象不用依賴于實(shí)現(xiàn),讓抽象和實(shí)現(xiàn)部分各自修改起來都很方便,使用組合(就是Abstraction類中包含了Implementor)的方式,降低了耦合度,同時(shí)也有助于分層,從而產(chǎn)生更好的結(jié)構(gòu)化系統(tǒng)。通過實(shí)際的項(xiàng)目經(jīng)驗(yàn),使用了橋接模式的代碼,對以后的擴(kuò)展有很大的幫助。

===================================================================

  • /*?
  • ????橋接模式:將抽象部分與它的實(shí)現(xiàn)部分相分離,他們可以獨(dú)立變化。?
  • ????合成/聚合復(fù)用原則CARP原則:面向?qū)ο笤O(shè)計(jì)的一個(gè)重要原則:?
  • ????????盡量使用合成/聚合,盡量不用使用類的繼承?
  • ????優(yōu)點(diǎn):?
  • ????(1)分離抽象接口及其實(shí)現(xiàn)部分。??
  • ????(2)橋接模式有時(shí)類似于多繼承方案,但是多繼承方案違背了類的單一職責(zé)原則?
  • ????(即一個(gè)類只有一個(gè)變化的原因),復(fù)用性比較差,而且多繼承結(jié)構(gòu)中類的?
  • ????個(gè)數(shù)非常龐大,橋接模式是比多繼承方案更好的解決方法。??
  • ????(3)橋接模式提高了系統(tǒng)的可擴(kuò)充性,在兩個(gè)變化維度中任意擴(kuò)展一個(gè)維度,都?
  • ????不需要修改原有系統(tǒng)。??
  • ????(4)實(shí)現(xiàn)細(xì)節(jié)對客戶透明,可以對用戶隱藏實(shí)現(xiàn)細(xì)節(jié)。??
  • ?
  • ????應(yīng)用舉例:?
  • ????????一個(gè)畫板的形狀可以是圓形的,正方形的,顏色可以是紅色,綠色,?
  • ????????那要求一個(gè)實(shí)現(xiàn)一個(gè)畫板就可以采用橋接模式?
  • ????Created?by?Phoenix_FuliMa?
  • */??
  • ??
  • #include?<iostream>??
  • using?namespace?std;??
  • ??
  • class?Implementor??
  • {??
  • public:??
  • ????virtual?void?Show()?{}??
  • };??
  • ??
  • class?Implementor1:public?Implementor??
  • {??
  • public:??
  • ????virtual?void?Show()??
  • ????{??
  • ????????cout<<"Implementor1?is?showing..."<<endl;??
  • ????}??
  • };??
  • ??
  • class?Implementor2:?public?Implementor??
  • {??
  • public:??
  • ????virtual?void?Show()??
  • ????{??
  • ????????cout<<"Implementor2?is?showing.."<<endl;??
  • ????}??
  • };??
  • ??
  • class?Abstractor??
  • {??
  • ????Implementor?*_implementor;??
  • public:??
  • ????virtual?void?SetImplementor(Implementor*?ot)??
  • ????{??
  • ????????this->_implementor?=?ot;??
  • ????}??
  • ????virtual?void?operate()??
  • ????{??
  • ????????_implementor->Show();??
  • ????}??
  • };??
  • ??
  • class?RefinedAbstractor:public?Abstractor??
  • {??
  • ??
  • };??
  • ??
  • int?main()??
  • {??
  • ????Implementor1?*?im1?=?new?Implementor1();??
  • ????Implementor2?*?im2?=?new?Implementor2();??
  • ??
  • ????RefinedAbstractor?*re?=?new?RefinedAbstractor();??
  • ????re->SetImplementor(im1);??
  • ????re->operate();??
  • ????re->SetImplementor(im2);??
  • ????re->operate();??
  • ??
  • ????delete?im1;??
  • ????delete?im2;??
  • ????delete?re;??
  • ??????
  • ????system("pause");??
  • ????return?0;??
  • } ?

  • 總結(jié)

    以上是生活随笔為你收集整理的C++设计模式之桥接模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。