設計模式---橋接模式
橋接模式
-
定義
橋接模式,將抽象部分與它的實現部分分離開來,使他們都可以獨立變化。並非兩部分完全獨立,而是將他們的繼承關係(強關聯),變成組合等關係(弱關聯),使抽象部分和實現部分,可以分別按照各自維度靈活變化,然後搭配起來使用,即橋接模式。
還有以下解釋:
將抽象和實現放在兩個不同的類層次中,使它們可以獨立地變化。——《Head First 設計模式》
將類的功能層次結構和實現層次結構相分離,使二者能夠獨立地變化,並在兩者之間搭建橋樑,實現橋接。—— 《圖解設計模式》
-
意圖(百度百科)
【GOF95】在提出橋樑模式的時候指出,橋樑模式的用意是"將抽象化(Abstraction)與實現化(
抽象化
存在於多個實體中的共同的概念性聯絡,就是抽象化。作為一個過程,抽象化就是忽略一些資訊,從而把不同的實體當做同樣的實體對待。
實現化
抽象化給出的具體實現,就是實現化。
脫耦
所謂耦合,就是兩個實體的行為的某種強關聯。而將它們的強關聯去掉,就是耦合的解脫,或稱脫耦。在這裡,脫耦是指將抽象化和實現化之間的耦合解脫開,或者說是將它們之間的強關聯改換成弱關聯。
將兩個角色之間的繼承關係改為聚合關係,就是將它們之間的強關聯改換成為弱關聯。因此,橋樑模式中的所謂脫耦,就是指在一個軟體系統的抽象化和實現化之間使用組合/聚合關係而不是繼承關係,從而使兩者可以相對獨立地變化。這就是橋樑模式的用意。
-
構成部分
-
實現方式
抽象類角色:定義抽象類Abstraction,使用Implementor角色提供的介面來定義基本功能介面。
修正抽象類:拓展抽象類角色,繼承抽象類Abstraction。
實現者角色:提供了用於抽象化角色的介面;它是一個抽象類或者介面。
具體的實現者角色:作為實現者角色的子類,通過實現具體方法來實現介面。
-
優點
1. 抽象與實現分離,兩部分可以任意拓展維度,拓展時不需修改原系統。
-
適用場景
1. 翻了網上的資料,以開關為例子的比較多。各類電器均需要不同開關,那麼開關作為抽象類(包含on,off方法),修正抽象類繼承開關抽象類,實現者(電器),具體實現者(檯燈,冰箱...)。 2. 使用畫筆畫不同顏色的不同圖形。
-
分析
以例2為例,
1. 以圖形Shape作為抽象角色(包含Draw()方法);
2. 建立修正抽象類,實現Draw方法
class Circle:public Shape
class Rectangle :public Shape
3. 實現者角色 :Color,(包含方法paint()方法)
4.具體實現者,繼承Color
-
程式碼
//main.h
#ifndef MAIN_H
#define MAIN_H
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "unistd.h"
#define RELEASE(p) {if(p) {delete p; p = NULL;}}
class IColor;
class IShape;
//////////////定義抽象角色//////////////
class IShape
{
public:
IShape(IColor* color){m_pColor = color;}
~IShape();
virtual void draw() = 0;
protected:
IColor* m_pColor;
};
////////////////定義修正抽象角色////////////////
class Circle : public IShape
{
public:
Circle(IColor* color);
virtual void draw();
private:
void drawCircle(){std::cout<<"draw a circle!"<<std::endl;}
};
class Rectangle : public IShape
{
public:
Rectangle(IColor* color);
virtual void draw();
private:
void drawRectangle(){std::cout<<"draw a rectangle!"<<std::endl;}
};
//////////////定義實現者角色//////////////
class IColor
{
public:
virtual void paintColor() = 0;
};
//////////////定義具體實現者//////////////
class Blue :public IColor
{
public:
virtual ~Blue(){std::cout<<"release Blue obj!"<<std::endl;}
virtual void paintColor();
};
class Yellow :public IColor
{
public:
virtual ~Yellow(){std::cout<<"release Yellow obj!"<<std::endl;}
virtual void paintColor();
};
#endif // MAIN_H
#include "main.h"
IShape::~IShape()
{
if(NULL == m_pColor)
{
delete m_pColor;
}
}
Circle::Circle(IColor* color):IShape(color)
{
std::cout<<"create a Circle Object!"<<std::endl;
}
void Circle::draw()
{
drawCircle();
m_pColor->paintColor();
}
Rectangle::Rectangle(IColor* color):IShape(color)
{
std::cout<<"create a Rectangle Object!"<<std::endl;
}
void Rectangle::draw()
{
drawRectangle();
m_pColor->paintColor();
}
void Blue::paintColor()
{
std::cout<<"paint blue color to the Shape!"<<std::endl;
}
void Yellow::paintColor()
{
std::cout<<"paint yellow color to the Shape!"<<std::endl;
}
int main(int argc, char *argv[])
{
std::cout<<"========Hello======"<<std::endl;
IColor * pBlueColor = new Blue();
IColor* pYellowColor = new Yellow();
IShape* pCircle = new Circle(pBlueColor);
IShape* pRectangle = new Rectangle(pYellowColor);
//畫一個藍色的圓
pCircle->draw();
//畫一個黃色的長方形
pRectangle->draw();
RELEASE(pCircle);
RELEASE(pRectangle);
getchar();
return 0;
}
輸出
========Hello======
create a Circle Object!
create a Rectangle Object!
draw a circle!
paint blue color to the Shape!
draw a rectangle!
paint yellow color to the Shape!
參考資料: