?????? 《設(shè)計(jì)模式》中說到將抽象部分與實(shí)現(xiàn)部分分離,使他們可以獨(dú)立的變化。
?????? 舉個(gè)例子更清楚些,好像我們平時(shí)玩的游戲中有 PS 版的,但是不是大家都有 PS 。這時(shí)我們等一段時(shí)間,一般會(huì)出 PC 版的或其他版本。由于支持游戲的平臺(tái)不一樣,但是如果我們編寫的游戲程序?yàn)榱诉m應(yīng)另一種平臺(tái)就要全部重新編寫的話豈不是很麻煩。再加上游戲本身的變動(dòng),一句眾人皆知的話:“死定了 ” 。
?????? 現(xiàn)在我們來看看 Bridge 橋接模式,看看它是如何解決類似問題的,首先我們看看 Bridge 模式的結(jié)構(gòu)。
??????
實(shí)際上,我們要做到的是把變化的部分提出,對(duì)其抽象,使變化獨(dú)立。那我們?nèi)绾巫瞿??通過組合的方式將變化獨(dú)立出去。將一個(gè)事物中的多個(gè)緯度變化分離。
?????? 下面舉一個(gè)場(chǎng)景來理解一下,還是用汽車舉例,我現(xiàn)在要一輛車( BMW 或 BORA )在路( WaterRoad 或 Cement )上跑?,F(xiàn)在有兩個(gè)緯度的變化點(diǎn):汽車和路。也就是上圖中的 AbstractChangePoint1 和 AbstractChangePoint2 。 AbstractChangePoint1 中包含有 AbstractChangePoint2 對(duì)象成員。。代碼實(shí)現(xiàn)如下:
??????
abstract
class
AbstractCar
??? {
???????
public
AbstractRoad road;
???????
public AbstractCar(AbstractRoad road)
??????? {
???????????
this.road = road;
??????? }
???????
public
abstract
string Run();
???????
public
abstract
string Stop();
??? }
???
abstract
class
AbstractRoad
??? {
???????
public
abstract
string GetRoadType();
}
以汽車為變化中心,用組裝的方式將兩個(gè)變化點(diǎn)結(jié)合起來。使路的變化和汽車隔離。下面來編寫路的實(shí)現(xiàn)。
class
WaterRoad:AbstractRoad
??? {
???????
public
override
string GetRoadType()
??????? {
???????????
return
"It is WaterRoad";
??????? }
?}
class
CementRoad:AbstractRoad
??? {
???????
public
override
string GetRoadType()
??????? {
???????????
return
"It is Cement";
??????? }
}
然后再來編寫汽車的實(shí)現(xiàn)
class
BMWCar:AbstractCar
??? {
???????
public BMWCar(AbstractRoad road)
??????????? : base(road)
??????? {
??????????
??????? }
???????
public
override
string Run()
??????? {
???????????
return
"BMW is running";
??????? }
???????
public
override
string Stop()
??????? {
???????????
return
"BMW is stopped";
??????? }
?}
class
BROACar:AbstractCar
??? {
???????
public BROACar(AbstractRoad road)
??????????? : base(road)
??????? {
???????????
??????? }
???????
public
override
string Run()
??????? {
???????????
return
"BROA is running";
??????? }
???????
public
override
string Stop()
??????? {
???????????
return
"BROA is stopped";
??????? }
? }
然后我們?cè)诳蛻舸a中調(diào)用這些類,首先,我想要這個(gè)場(chǎng)景是BMW在WaterRoad上跑,客戶端代碼如下:
static
void
??????? {
???????????
AbstractCar car = newBMWCar(newWaterRoad());
???????????
Console.WriteLine(car.road.GetRoadType());
???????????
Console.WriteLine(car.Run());
???????????
Console.WriteLine(car.Stop());
???????????
Console.Read();
??????? }
實(shí)現(xiàn)結(jié)果如下:
It is WaterRoad
BMW is running
BMW is stopped
如果我現(xiàn)在要一輛BORA在Cement上跑,我們只要稍微修改一下car的實(shí)例化就可以,代碼如下:
static
void
??????? {
???????????
AbstractCar car = newBROACar(newCementRoad());
???????????
Console.WriteLine(car.road.GetRoadType());
???????????
Console.WriteLine(car.Run());
???????????
Console.WriteLine(car.Stop());
???????????
Console.Read();
???? }
實(shí)現(xiàn)結(jié)果如下:
It is Cement
BROA is running
BROA is stopped
?????? 最后我們?cè)賮碚f說 Bridge 模式的要點(diǎn):
?????? 1 、 Bridge 模式使用“對(duì)象間的組合關(guān)系”解耦了抽象和實(shí)現(xiàn)之間固有的綁定關(guān)系,使得抽象和實(shí)現(xiàn)可以沿著各自的緯度來變化。
2 、所謂抽象和實(shí)現(xiàn)沿著各自緯度的變化,即“子類化”它們,得到各個(gè)子類之后,便可以任意組合它們。
3 、 Bridge 模式有時(shí)候類似于多繼承方案,但是多繼承方案往往違背單一職責(zé)原則(即一個(gè)類只有一個(gè)變化的原因),復(fù)用性比較差。 Bridge 模式是比多繼承方案更好的解決方法。
4 、 Bridge 模式的應(yīng)用一般在“兩個(gè)非常強(qiáng)的變化緯度”,有時(shí)候即使有兩個(gè)變化的緯度,但是某個(gè)方向的變化緯度并不劇烈——換言之兩個(gè)變化不會(huì)導(dǎo)致縱橫交錯(cuò)的結(jié)果,并不一定要使用 Bridge 模式。