程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> C#面向對象設計模式縱橫談 學習筆記8 Bridge橋接(結構型模式)

C#面向對象設計模式縱橫談 學習筆記8 Bridge橋接(結構型模式)

編輯:.NET實例教程

橋接模式的動機

假設我們有一個坦克游戲的開發,那麼這個坦克有多種類型,並且這個游戲要支持多種平台的游戲

事實上由於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模式。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved