亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++設計模式編程中使用Bridge橋接模式的完全攻略

2020-05-23 14:07:25
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了C++設計模式編程中使用Bridge橋接模式的完全攻略,Bridge將抽象部分與它的實現部分分離,使它們都可以獨立地變化需要的朋友可以參考下
 

橋接模式將抽象(Abstraction)與實現(Implementation)分離,使得二者可以獨立地變化。

橋接模式典型的結構圖為:

C++,設計模式編程,Bridge,橋接模式

在橋接模式的結構圖中可以看到,系統被分為兩個相對獨立的部分,左邊是抽象部分,右邊是實現部分,這兩個部分可以互相獨立地進行修改:例如上面問題中的客戶需求變化,當用戶需求需要從 Abstraction 派生一個具體子類時候,并不需要像上面通過繼承方式實現時候需要添加子類 A1 和 A2 了。另外當上面問題中由于算法添加也只用改變右邊實現(添加一個具體化子類),而右邊不用在變化,也不用添加具體子類了。

一切都變得 elegant!

橋接模式號稱設計模式中最難理解的模式之一,關鍵就是這個抽象和實現的分離非常讓人奇怪,大部分人剛看到這個定義的時候都會認為實現就是繼承自抽象,那怎么可能將他們分離呢。

《大話設計模式》中就Bridge模式的解釋:

手機品牌和軟件是兩個概念,不同的軟件可以在不同的手機上,不同的手機可以有相同的軟件,兩者都具有很大的變動性。如果我們單獨以手機品牌或手機軟件為基類來進行繼承擴展的話,無疑會使類的數目劇增并且耦合性很高,(如果更改品牌或增加軟件都會增加很多的變動)兩種方式的結構如下:

C++,設計模式編程,Bridge,橋接模式

C++,設計模式編程,Bridge,橋接模式

所以將兩者抽象出來兩個基類分別是PhoneBrand和PhoneSoft,那么在品牌類中聚合一個軟件對象的基類將解決軟件和手機擴展混亂的問題,這樣兩者的擴展就相對靈活,剪短了兩者的必要聯系,結構圖如下:

C++,設計模式編程,Bridge,橋接模式

這樣擴展品牌和軟件就相對靈活獨立,達到解耦的目的!

抽象基類及接口:

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.將可以共享的變化部分,抽離出來,減少了代碼的重復信息。

3.對象的具體實現可以更加靈活,可以滿足多個因素變化的要求。

缺點
客戶必須知道選擇哪一種類型的實現。
設計中有超過一維的變化我們就可以用橋模式。如果只有一維在變化,那么我們用繼承就可以圓滿的解決問題。

代碼示例:

Abstraction.h

#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;//私有成員};#endifAbstraction.cpp#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();}AbstractImplement.h#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:};#endifAbstractImplement.cpp#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;}

main.cpp

#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;}

代碼說明:
Bridge模式將抽象和實現分別獨立實現,在代碼中就是Abstraction類和AbstractionImplement類。

使用組合(委托)的方式將抽象和實現徹底地解耦,這樣的好處是抽象和實現可以分別獨立地變化,系統的耦合性也得到了很好的降低。
GoF的那句話中的“實現”該怎么去理解:“實現”特別是和“抽象”放在一起的時候我們“默認”的理解是“實現”就是“抽象”的具體子類的實現,但是這里GoF所謂的“實現”的含義不是指抽象基類的具體子類對抽象基類中虛函數(接口)的實現,是和繼承結合在一起的。而這里的“實現”的含義指的是怎么去實現用戶的需求,并且指的是通過組合(委托)的方式實現的,因此這里的實現不是指的繼承基類、實現基類接口,而是指的是通過對象組合實現用戶的需求。

實際上上面使用Bridge模式和使用帶來問題方式的解決方案的根本區別在于是通過繼承還是通過組合的方式去實現一個功能需求。

備注:

由于實現的方式有多種,橋接模式的核心就是把這些實現獨立出來,讓他們各自變化。

將抽象部分與它的實現部分分離:實現系統可能有多角度(維度)分類,每一種分類都可能變化,那么就把這種多角度分離出來讓它們獨立變化,減少它們之間的耦合。

在發現需要多角度去分類實現對象,而只用繼承會造成大量的類增加,不能滿足開放-封閉原則時,就要考慮用Bridge橋接模式了。

合成/聚合復用原則:盡量使用合成/聚合,精良不要使用類繼承。
優先使用對象的合成/聚合將有助于保持每個類被封裝,并被集中在單個任務上。這樣類和類繼承層次會保持較小規模,并且不太可能增長為不可控制的龐然大物。

適用場景:

  • 你不希望在抽象和它的實現部分之間有一個固定的綁定關系。例如這種情況可能是因為,在程序運行時刻實現部分應可以被選擇或者切換。
  • 類的抽象以及它的實現都應該可以通過生成子類的方法加以擴充。這時B r i d g e 模式使你可以對不同的抽象接口和實現部分進行組合,并分別對它們進行擴充。
  • 對一個抽象的實現部分的修改應對客戶不產生影響,即客戶的代碼不必重新編譯。
  • (C + +)你想對客戶完全隱藏抽象的實現部分。在C + +中,類的表示在類接口中是可見的。
  • 有許多類要生成。這樣一種類層次結構說明你必須將一個對象分解成兩個部分。R u m b a u g h 稱這種類層次結構為“嵌套的普化”(nested generalizations )。
  • 你想在多個對象間共享實現(可能使用引用計數),但同時要求客戶并不知道這一點。一個簡單的例子便是C o p l i e n 的S t r i n g 類[ C o p 9 2 ],在這個類中多個對象可以共享同一個字符串表示(S t r i n g R e p )。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久精品在线观看| 黑人与娇小精品av专区| 久久久久久久久久国产| 欧美日韩在线免费观看| 成人黄色av播放免费| 欧美中文字幕视频在线观看| 亚洲国产97在线精品一区| 亚洲人成网站在线播| 欧美最近摘花xxxx摘花| 日韩电影大片中文字幕| 日本久久久久久久久久久| 国产精品美女免费视频| 日韩精品免费看| 国产精品av免费在线观看| 久久久久亚洲精品成人网小说| 国产亚洲免费的视频看| 国产精品久久中文| 日韩精品视频在线观看免费| 不卡av电影在线观看| 日韩电影第一页| 88国产精品欧美一区二区三区| 亚洲国产精品99久久| 成人欧美在线视频| 91午夜在线播放| 98精品国产高清在线xxxx天堂| 国产精品一区二区av影院萌芽| 成人黄色影片在线| 91高清在线免费观看| 国产亚洲精品成人av久久ww| 久久久国产视频| 日韩中文字幕久久| 亚洲国产精品成人av| 日韩亚洲精品电影| 日本精品免费一区二区三区| 久久99国产精品久久久久久久久| 日本亚洲欧洲色α| 国产日韩av在线播放| 久久久国产精彩视频美女艺术照福利| 国产美女精品视频免费观看| 日韩高清电影好看的电视剧电影| 色偷偷偷亚洲综合网另类| 成人久久一区二区三区| 欧美做受高潮1| 欧美日韩裸体免费视频| 国产成人精品免费视频| 日韩在线观看你懂的| 一个人看的www欧美| 亚洲国产欧美一区| 日韩av在线免费观看一区| 中文日韩电影网站| 亚洲日韩中文字幕在线播放| 97在线精品国自产拍中文| 久久久亚洲网站| 国产精品美女久久久免费| 中文字幕日韩精品在线| 欧美大全免费观看电视剧大泉洋| 欧美一级淫片播放口| 国产精品激情av在线播放| 色偷偷av亚洲男人的天堂| 亚洲欧洲高清在线| 91精品91久久久久久| 97在线视频免费观看| 裸体女人亚洲精品一区| 久久免费成人精品视频| 欧洲日韩成人av| 日本成人在线视频网址| 亚洲国产欧美一区| 国产成人97精品免费看片| 欧美人交a欧美精品| 欧美裸体男粗大视频在线观看| 欧美精品成人91久久久久久久| 亚洲最新视频在线| 亚洲精品成人久久| 91精品国产亚洲| 韩剧1988免费观看全集| 日韩在线小视频| 亚洲精品白浆高清久久久久久| 日韩色av导航| 久久久久久亚洲精品不卡| 日韩av免费在线| www高清在线视频日韩欧美| 亚洲社区在线观看| 国产精品高清网站| 日韩电影免费观看在线| 97在线视频免费播放| 日韩av在线资源| 日韩大陆欧美高清视频区| 久久久久久有精品国产| 久久九九全国免费精品观看| 在线观看日韩欧美| 精品无人国产偷自产在线| 国产综合久久久久| 国产日韩欧美在线播放| 欧美日韩国产一区二区| 欧美日本黄视频| 国产一区二区动漫| 国产丝袜一区视频在线观看| 粉嫩老牛aⅴ一区二区三区| 欧美日韩视频免费播放| 九九久久国产精品| 欧美精品在线视频观看| 欧美香蕉大胸在线视频观看| 欧美激情亚洲另类| 亚洲一二在线观看| 亚洲国产日韩欧美在线图片| 亚洲国产精品高清久久久| 欧美中文在线字幕| 国产精品久久久久9999| 午夜精品国产精品大乳美女| 欧美日韩国产成人高清视频| 亚洲欧洲视频在线| 亚洲色图狂野欧美| 久久久国产视频91| 亚洲成色999久久网站| 97精品国产97久久久久久| 一区二区三区无码高清视频| 国产97在线亚洲| 成人有码视频在线播放| 国产成人avxxxxx在线看| 欧美理论在线观看| 性色av一区二区三区在线观看| 亚洲精品之草原avav久久| 欧美成年人在线观看| 日韩欧美在线中文字幕| 欧美高清激情视频| 欧美午夜丰满在线18影院| xxx欧美精品| 亚洲成av人乱码色午夜| 亚洲第一视频网站| 伊人成人开心激情综合网| 浅井舞香一区二区| 国产精品18久久久久久麻辣| 国产精品wwww| 日韩欧美有码在线| 亲爱的老师9免费观看全集电视剧| 8x拔播拔播x8国产精品| 国产精品视频永久免费播放| 不卡av电影院| 国产精品美女免费| 欧美性xxxx极品hd欧美风情| 国产亚洲精品久久久久久777| 2019国产精品自在线拍国产不卡| 国产在线观看精品一区二区三区| 琪琪亚洲精品午夜在线| 欧美亚洲一区在线| 色老头一区二区三区| 精品少妇一区二区30p| 91高清视频免费观看| 日韩欧美成人区| 成人亲热视频网站| 国产精品美女久久久免费| 伊人久久免费视频| 成人免费网站在线看| 欧美亚洲成人精品| 国产视频精品免费播放| 日韩成人中文电影| 亚洲第一页中文字幕| 亚洲欧美另类人妖| 国产精品网站视频| 久久夜色精品亚洲噜噜国产mv| 亚洲国产高清福利视频| 国产精品一区二区三区免费视频| 91精品在线播放| 国产婷婷97碰碰久久人人蜜臀|