橋接模式的動機
假設我們有一個坦克游戲的開發,那麼這個坦克有多種類型,並且這個游戲要支持多種平台的游戲
事實上由於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模式的幾個要點