最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

.Net結構型設計模式之橋接模式(Bridge)

 更新時間:2022年05月25日 15:06:58   作者:springsnow  
這篇文章介紹了.Net結構型設計模式之橋接模式(Bridge),文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一、動機(Motivation)

在很多游戲場景中,會有這樣的情況:【裝備】本身會有的自己固有的邏輯,比如槍支,會有型號的問題,同時現(xiàn)在很多的游戲又在不同的介質平臺上運行和使用,這樣就使得游戲的【裝備】具有了兩個變化的維度——一個變化的維度為“平臺的變化”,另一個變化的維度為“型號的變化”。如果我們要寫代碼實現(xiàn)這款游戲,難道我們針對每種平臺都實現(xiàn)一套獨立的【裝備】嗎?復用在哪里?如何應對這種“多維度的變化”?如何利用面向對象技術來使得【裝備】可以輕松地沿著“平臺”和“型號”兩個方向變化,而不引入額外的復雜度?

二、意圖(Intent)

將抽象部分與實現(xiàn)部分分離,使它們都可以獨立地變化。

橋模式不能只是認為是抽象和實現(xiàn)的分離,它其實并不僅限于此。其實兩個都是抽象的部分,更確切的理解,應該是將一個事物中多個維度的變化分離。

三、結構(Structure)

其中imp的地方就是一個組合。Abstraction就是我們例子中的Tank,它的子類RefinedAbstraction就是T50等型號。Implementor是TankPlatformImplementation類,ConcreteImplementorA和ConcreteImplementorB分別是PCTankImplementation和MobileTankImplementation。

整個設計模式的關鍵就是組合的使用。

四、模式的組成

橋接模式的結構包括Abstraction、RefinedAbstraction、Implementor、ConcreteImplementorA和ConcreteImplementorB五個部分,其中: 
(1)、抽象化角色(Abstraction):抽象化給出的定義,并保存一個對實現(xiàn)化對象(Implementor)的引用。 
(2)、修正抽象化角色(Refined Abstraction):擴展抽象化角色,改變和修正父類對抽象化的定義。 
(3)、實現(xiàn)化角色(Implementor):這個角色給出實現(xiàn)化角色的接口,但不給出具體的實現(xiàn)。必須指出的是,這個接口不一定和抽象化角色的接口定義相同,實際上,這兩個接口可以非常不一樣。實現(xiàn)化角色應當只給出底層操作,而抽象化角色應當只給出基于底層操作的更高一層的操作。 
(4)、具體實現(xiàn)化角色(Concrete Implementor):這個角色給出實現(xiàn)化角色接口的具體實現(xiàn)。 
在橋接模式中,兩個類Abstraction和Implementor分別定義了抽象與行為類型的接口,通過調用兩接口的子類實現(xiàn)抽象與行為的動態(tài)組合。 

五、橋接模式的具體代碼實現(xiàn)

假如我們需要開發(fā)一個同時支持PC和手機端的坦克游戲,游戲在PC和手機上功能都一樣,都有同樣的類型,面臨同樣的功能需求變化,比如坦克可能有很多種不同的型號:T50,T75,T90……

對于其中的坦克設計,我們可能很容易設計出來一個Tank的抽象基類,然后各種不同型號的Tank繼承自該類;

這一步實現(xiàn)一點問題也沒有,也符合開閉原則,繼續(xù)往下看。

另外的變化原因

但是PC和手機上的圖形繪制、聲效、操作等實現(xiàn)完全不同……因此對于各種型號的坦克,都要提供各種不同平臺上的坦克實現(xiàn):

我們一般會設計成這樣,但是這樣看很怪,這樣的設計會帶來很多問題:有很多重復代碼,類的結構過于復雜,難以維護,最致命的是引入任何新平臺,比如在TV上的Tank游戲,都會讓整個類層級結構復雜化。我們做軟件,修改的時候,修改的越少越好,說明隔離的比較好。

public abstract class TankModel
{
    protected TankPlatformImplementation _tankImp;

    public TankModel(TankPlatformImplementation tankImp)
    {
        _tankImp = tankImp;
    }
    public abstract void Run();
}

public abstract class TankPlatformImplementation
{
    public abstract void MoveTankTo(int x, int y);
    public abstract void DrawTank();
    public abstract void Attack();
}

/// 

/// PC坦克
/// 
public class PCTankImplatation : TankPlatformImplementation
{
    string _tankModel;
    public PCTankImplatation(string tankModel)
    {
        _tankModel = tankModel;
    }
    /// 

    /// 繪制坦克
    /// 
    public override void DrawTank()
    {
        Console.WriteLine(_tankModel + "PC坦克繪制成功!");
    }
    /// 

    /// 坦克移動
    /// 
    /// x坐標
    /// y坐標
    public override void MoveTankTo(int x, int y)
    {
        Console.WriteLine(_tankModel + "PC坦克已經移動到了坐標(" + x + "," + y + ")處");
    }
    /// 

    /// 攻擊
    /// 
    public override void Attack()
    {
        Console.WriteLine(_tankModel + "PC坦克開始攻擊");
    }
}
/// 

/// T50型號坦克
/// 
public class T50 : TankModel
{
    public T50(TankPlatformImplementation tankImp) : base(tankImp) { }
    public override void Run()
    {
        _tankImp.DrawTank();
        _tankImp.MoveTankTo(100, 100);
        _tankImp.Attack();
    }
}

/// 

/// 客戶端調用
/// 
public class App
{
    void Main(string[] agrs)
    {
        T50 t = new T50(new PCTankImplatation("T50"));
        t.Run();
    }
}

使用了橋接模式后,當需求發(fā)生變化后就很容易來應對了,假如現(xiàn)在又多了一種T60型號的坦克,并且添加了一個手機平臺。只需要添加T60型號的具體類和手機平臺具體類即可,如下:

/// 
/// 手機坦克
/// 
public class MobileTankImplatation : TankPlatformImplementation
{
    string _tankModel;
    public MobileTankImplatation(string tankModel)
    {
        _tankModel = tankModel;
    }
    /// 

    /// 繪制坦克
    /// 
    public override void DrawTank()
    {
        Console.WriteLine(_tankModel+"Mobile坦克繪制成功!");
    }
    /// 

    /// 坦克移動
    /// 
    /// x坐標
    /// y坐標
    public override void MoveTankTo(int x, int y)
    {
        Console.WriteLine(_tankModel+"Mobile坦克已經移動到了坐標(" + x + "," + y + ")處");
    }
    /// 

    /// 攻擊
    /// 
    public override void Attack()
    {
        Console.WriteLine(_tankModel+"Mobile坦克開始攻擊");
    }
}
/// 

/// T60型號坦克
/// 
public class T60 : TankModel
{
    public T60(TankPlatformImplementation tankImp) : base(tankImp) { }
    public override void Run()
    {
        _tankImp.DrawTank();
        _tankImp.MoveTankTo(400, 100);
        _tankImp.Attack();
    }
}

添加這兩個類后現(xiàn)在我們有T50型號、 T60型號 、PC平臺、手機平臺,雖然只添加了兩個類,但現(xiàn)在有了四種組合,看客戶端代碼的調用:

/// 
/// 客戶端調用
/// 
public class App
{
    void Main(string[] agrs)
    {
       //T50在PC上
        T50 t50PC = new T50(new PCTankImplatation("T50"));
       t50PC.Run();
       //T50在Mobile上
        T50 t50Mobile = new T50(new MobileTankImplatation("T50"));
       t50Mobile.Run();
       //T60在PC上
        T60 t60PC = new T60(new PCTankImplatation("T60"));
       t60PC.Run();
       //T60在Mobile上
        T60 t60Mobile = new T60(new MobileTankImplatation("T60"));
       t60Mobile.Run();
    }
}

六、橋接模式的實現(xiàn)要點:

1.Bridge模式使用“對象間的組合關系”解耦了抽象和實現(xiàn)之間固有的綁定關系,使得抽象和實現(xiàn)可以沿著各自的維度來變化。 
2.所謂抽象和實現(xiàn)沿著各自維度的變化,即“子類化”它們,得到各個子類之后,便可以任意組合它們,從而獲得不同平臺上的不同型號。 
3.Bridge模式有時候類似于多繼承方案,但是多繼承方案往往違背了類的單一職責原則(即一個類只有一個變化的原因),復用性比較差。Bridge模式是比多繼承方案更好的解決方法。 
4.Bridge模式的應用一般在“兩個非常強的變化維度”,有時候即使有兩個變化的維度,但是某個方向的變化維度并不劇烈——換言之兩個變化不會導致縱橫交錯的結果,并不一定要使用Bridge模式。 

1、橋接模式的優(yōu)點:

(1)、把抽象接口與其實現(xiàn)解耦。 
(2)、抽象和實現(xiàn)可以獨立擴展,不會影響到對方。 
(3)、實現(xiàn)細節(jié)對客戶透明,對用于隱藏了具體實現(xiàn)細節(jié)。 

2、橋接模式的缺點:

增加了系統(tǒng)的復雜度 

3、橋接模式的使用場景:

(1)、如果一個系統(tǒng)需要在構件的抽象化角色和具體化角色之間添加更多的靈活性,避免在兩個層次之間建立靜態(tài)的聯(lián)系。 
(2)、設計要求實現(xiàn)化角色的任何改變不應當影響客戶端,或者實現(xiàn)化角色的改變對客戶端是完全透明的。 
(3)、需要跨越多個平臺的圖形和窗口系統(tǒng)上。 
(4)、 一個類存在兩個獨立變化的維度,且兩個維度都需要進行擴展。

下面是針對上面的例子,多繼承接口的一種寫法:

這樣PCT50既需要寫T50的實現(xiàn),又要寫Platform的實現(xiàn),它把型號和平臺的變化都引入了PCT50。這樣就把兩個本不該扭在一起的事務扭在了一起,這樣的設計更加糟糕,而且也違背了類的單一職責原則。

Bridge模式的應用一般在“兩個非常強的變化維度”,有時候即使有兩個變化的維度,但是某個方向的變化維度并不劇烈——換言之兩個變化不會導致縱橫交錯的結果,并不一定要使用Bridge模式。

橋模式并不同于適配器模式,適配器模式其實是一個事后諸葛亮,當發(fā)現(xiàn)以前的東西不適用了才去做一個彌補的措施。橋模式相對來說所做的改變比適配器模式早,它可以適用于有兩個甚至兩個以上維度的變化。

到此這篇關于.Net結構型設計模式之橋接模式(Bridge)的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

最新評論

浮山县| 济宁市| 峨山| 灵台县| 高台县| 鱼台县| 台北县| 东源县| 任丘市| 河池市| 高陵县| 兰考县| 茂名市| 玉溪市| 长寿区| 金阳县| 沙田区| 莲花县| 太和县| 岑巩县| 墨脱县| 晋中市| 乡宁县| 馆陶县| 阿勒泰市| 新巴尔虎右旗| 钟祥市| 建始县| 菏泽市| 老河口市| 上思县| 邛崃市| 蒙山县| 禹城市| 无为县| 建昌县| 东城区| 陇川县| 漳平市| 宜阳县| 关岭|