橋接模式的動機
假設我們有一個坦克游戲的開發,那麼這個坦克有多種類型,並且這個游戲要支持多種平台的游戲
事實上由於Tank類型的固有邏輯,使得Tank類型具有了兩個變化的維度--一個變化的維度為"平台的變化",一個變化的維度為"型號的變化"。如何應對這種"多維度的變化"?如何利用面向對象技術來使得Tank類型可以輕松地沿著"平台"和"型號"兩個方向變化,而不引入額外的復雜度?
橋接模式的意圖
將抽象部分與實現部分分離,使它們都可以獨立地變化。
下面用代碼來實現

public abstract class Tank


...{

protected TankPlatformImplementation tankImp;


public Tank(TankPlatformImplementation tankImp)


...{

this.tankImp = tankImp;

}


public TankPlatformImplementation TanImp


...{

get


...{

return this.tankImp;

}

set


...{

this.tankImp = value;

}

}


public abstract void Shot();

public abstract void Run();

public abstract void Stop();

}
這是一個坦克的抽象基類,它是比較穩定的,表明坦克的類型,我們現在先不看TankPlatformImplementation,在後面來敘述它。
如果我們要這個坦克有多種類型的坦克,並且也支持多個平台,那麼我們會有一個種類的坦克繼承於Tank類型,然後還要有這種類型坦克的各個平台的坦克繼承於這種坦克類型,那麼我們有n種坦克,就會有n × 2種實現平台的坦克類型,那麼我們需要隔離這種變化。我們將平台不用繼承,使用組合,將平台和坦克種類隔離開來。
現在看看坦克類型

public class TankT50 : Tank


...{

public TankT50(TankPlatformImplementation tankImp)

: base(tankImp)


...{

}


public override void Shot()


...{

tankImp.DOShot();

}


public override void Run()


...{

tankImp.MoveTank(new Point());

}


public override void Stop()


...{

//tankImp....;

}

}


public class TankT75 : Tank


...{

public TankT75(TankPlatformImplementation tankImp)

: base(tankImp)


...{

}


public override void Shot()

...{

tankImp.DOShot();

}


public override void Run()


...{

tankImp.MoveTank(new Point());

}


public override void Stop()


...{

//tankImp....;

}

}


public class TankT90 : Tank


...{

public TankT90(TankPlatformImplementation tankImp)

: base(tankImp)


...{

}


public override void Shot()


...{

tankImp.DOShot();

}


public override void Run()


...{

tankImp.MoveTank(new Point());

}


public override void Stop()


...{

//tankImp....;

}

}
那麼我們在坦克種類實現的時候,使用平台類型來表現出坦克的使用。
下面看看坦克平台是如何實現

public abstract class TankPlatformImplementation


...{

public abstract void MoveTank(Point to);

public abstract void DrawTank();

public abstract void DOShot();

}
這是一個坦克平台的抽象類,規定了在各種平台下坦克需要作的動作

public class PCTankImplementation : TankPlatformImplementation


...{

public override void MoveTank(Point to)


...{

}


public override void DrawTank()


...{

}


public override void DOShot()


...{

}

}


public class MobileTankImplementation : TankPlatformImplementation


...{

public override void MoveTank(Point to)


...{

}


public override void DrawTank()


...{

}


public override void DOShot()


...{

}

}
那麼我們在各種平台下的動作由各種平台的派生類來實現。我們可以看出平台類作為一個橋接,將另一個緯度的變化轉換了。
那麼我們如何創建一個坦克類型

static void Main(string[] args)


...{

MobileTankImplementation imp = new MobileTankImplementation();

TankT50 tank = new TankT50(imp);

}
我們可以先規定游戲運行的平台,使用當前平台來使用坦克種類在各種平台殺那個的表現。
Bridge模式的幾個要點
- Bridge模式使用"對象間的組合關系"解耦了抽象和實現之間固有的綁定關系,使得抽象(Tank的型號)和實現(不同的平台)可以沿著各自的維度來變化。
- 所謂抽象和實現沿著各自緯度的變化,即"子類化"它們,比如不同的Tank型號子類,和不同的平台子類)。得到各個子類之後,便可以任意組合它們,從而獲得不同平台上的不同型號。
- Bridge模式有時候類似於多繼承方案,但是多繼承方案往往違背單一職責原則(即一個類只有一個變化的原因),復用性比較差。Bridge模式是比多繼承方案更好的解決方法。
- Bridge模式的應用一般在"兩個非常強的變化維度",有時候即使有兩個變化的維度,但是某個方向的變化維度並不劇烈--換言之兩個變化不會導致縱橫交錯的結果,並不一定要使用Bridge模式。