結構型模式之 橋接模式
前言
設想如果要繪製矩形、圓形、橢圓、正方形,我們至少需要4個形狀類,這時如果繪製的圖形需要具有不同的顏色,如紅色、綠色、藍色等,此時至少有如下兩種設計方案:
- 第一種設計方案是爲每一種形狀都提供一套各種顏色的版本。
- 第二種設計方案是根據實際需要對形狀和顏色進行組合
對於有兩個變化維度(即兩個變化的原因)的系統,採用方案二來進行設計系統中類的個數更少,且系統擴展更爲方便。設計方案二即是橋接模式的應用。橋接模式將繼承關係轉換爲關聯關係,從而降低了類與類之間的耦合,減少了代碼編寫量。
模式定義
橋接模式(Bridge Pattern):將抽象部分與它的實現部分分離,使它們都可以獨立地變化。它是一種對象結構型模式,又稱爲柄體(Handle and Body)模式或接口(Interface)模式。
模式結構
橋接模式包含如下角色:
- Abstraction:抽象類
- RefinedAbstraction:擴充抽象類
- Implementor:實現類接口
- ConcreteImplementor:具體實現類
UML類圖
適用場景
- 在以下情況下可以使用橋接模式:
如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的繼承聯繫,通過橋接模式可以使它們在抽象層建立一個關聯關係。
抽象化角色和實現化角色可以以繼承的方式獨立擴展而互不影響,在程序運行時可以動態將一個抽象化子類的對象和一個實現化子類的對象進行組合,即系統需要對抽象化角色和實現化角色進行動態耦合。
一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴展。
雖然在系統中使用繼承是沒有問題的,但是由於抽象化角色和具體化角色需要獨立變化,設計要求需要獨立管理這兩者。
對於那些不希望使用繼承或因爲多層次繼承導致系統類的個數急劇增加的系統,橋接模式尤爲適用。
- 看看大神怎麼用
一個Java桌面軟件總是帶有所在操作系統的視感(LookAndFeel),如果一個Java軟件是在Unix系統上開發的,那麼開發人員看到的是Motif用戶界面的視感;在Windows上面使用這個系統的用戶看到的是Windows用戶界面的視感;而一個在Macintosh上面使用的用戶看到的則是Macintosh用戶界面的視感,Java語言是通過所謂的Peer架構做到這一點的。Java爲AWT中的每一個GUI構件都提供了一個Peer構件,在AWT中的Peer架構就使用了橋接模式
- 個人理解
橋接模式解決了兩個元素變化的問題,可以動態的爲元素1設置不同的元素2,例如夜間模式,變化的維度就是時間和主題,白天可以設置爲白色主題,夜間設置爲黑色主題,並且再多變化也可以輕鬆擴展。
高清有碼
否一可三坡:爲了更容易理解,類名我用了橋接模式中的角色名,而方法名則是例子中的名字,如果看管您不喜歡,我在這給您磕頭賠不是了……
我們對妹子的抗性簡直爲0,反正我是這樣,不知道要不要加們。沒有了妹子如同患了色盲症一般,世界都沒有了色彩。
不管高矮俊醜,妹子具都有makeYouHappy的功效,這樣就抽象出一個妹子類了。好吧……醜去掉。
而makeYouHappy的技能簡直五花八門,這樣可以定義出一個實現類接口,而她們個個身懷絕技都有自己的skill技能。
Abstraction抽象類接口
/**
* 抽象類接口
* Created by R on 2016/8/16.
*/
public abstract class Abstraction {
protected Implementor mImp;
public Abstraction(Implementor implementor){
this.mImp = implementor;
}
public abstract void makeYouHappy();
}
RefinedAbstractionA 、B抽象實現類A和B
/**
* 抽象類實現類
* Created by R on 2016/8/16.
*/
public class RefinedAbstractionA extends Abstraction{
public RefinedAbstractionA(Implementor implementor) {
super(implementor);
}
@Override
public void makeYouHappy() {
System.out.println("A類型的妹子");
mImp.skill();
}
}
/**
* 抽象類實現類
* Created by R on 2016/8/16.
*/
public class RefinedAbstractionB extends Abstraction{
public RefinedAbstractionB(Implementor implementor) {
super(implementor);
}
@Override
public void makeYouHappy() {
System.out.println("B類型的妹子");
mImp.skill();
}
}
Implementor實現類接口
/**
* 實現類接口
* Created by R on 2016/8/16.
*/
public interface Implementor {
void skill();
}
ConcreteImplementorA、B具體實現 A 和 B
/**
* 具體實現
* Created by R on 2016/8/16.
*/
public class ConcreteImplementorA implements Implementor{
@Override
public void skill() {
System.out.println("陪你擼啊擼~");
}
}
/**
* 具體實現
* Created by R on 2016/8/16.
*/
public class ConcreteImplementorB implements Implementor{
@Override
public void skill() {
System.out.println("陪你滾呀滾~");
}
}
Client使用者
/**
* 使用者
* Created by R on 2016/8/16.
*/
public class Client {
public void main(){
Implementor impA = new ConcreteImplementorA();
Implementor impB = new ConcreteImplementorB();
Abstraction absA = new RefinedAbstractionA(impA);
Abstraction absB = new RefinedAbstractionA(impB);
absA.makeYouHappy();
absB.makeYouHappy();
}
}
輸出:
A類型的妹子
陪你擼啊擼
B類型的妹子
陪你滾呀滾
總結
理解橋接模式,重點需要理解如何將抽象化(Abstraction)與實現化(Implementation)脫耦,使得二者可以獨立地變化。別名”柄體模式(Head and Body)”更能形象的表達他的模式結構,他由一個抽象類Head和一個實現接口Body。抽象話把不同的實體當做同樣的實體對待;實現化針對抽象化給出的具體實現。他們之間是可逆的。
簡而言之:同一個世界,不同的夢想!