Design Patterns之Bridge Pattern學習總結
今晚看了Bridge模式,本想總結時再自己想個例子,不過沒有想到,于是就引用李建忠老師的C#設計模式之Bridge模式中的坦克例子吧,加深一下理解。文中要是有不對的地方還請大家指點。
Bidge模式,是為了應對多維度的變化的情況,先不管那么多,例子先上。
假設現在要開發一個平常玩的那種坦克游戲,但這個游戲要有兩個版本,PC版的和手機版的,其中坦克有許多型號,但PC版所有的坦克,手機版中也要有,而且功能要完全相同的,要不然就太不公平,玩的沒意思了,但是PC版和手機版的實現肯定是有所不同的,硬件性能相差那么大,PC版的坦克外觀可能會是非常逼真的3D效果,但手機版的可能只是二維的。
于是,我就畫出了下面這張圖:
![]()
其中Tank是一個抽象基類,其中假設有Shoot(),Move(),Stop(),Turn()方法,分別表示射擊、移動、停住、轉彎,而T50和T75是兩個型號的坦克,都繼承于Tank,它們將實現具體的方法。但我們是要有PC和Mobile兩個平臺的,于是又有了PC版的T50:PCT50,PC版的T50:MobileT50,T75也一樣,有兩個平臺。
實現代碼:
Code
這么做乍看起來是挺合理的,但是,如果我們要再加一個型號T80呢?那還要再來一個T80繼承Tank,PCT80和MobileT80再繼承T80,如果要增加很多的型號,那我們就要這么寫很多個類,更關鍵的是,PC平臺和Mobile平臺上的坦克的功能是完全一樣的,比如他們的發炮方法,轉彎方法,所以,我們在PCT50和MobileT50中難免會有重復的代碼,PCT75和MobileT75中也會有,那我們不是可以拷貝代碼嗎?當然可以,但這絕對不是好辦法,而且當我們要增加其它的平臺,那工作量又得大增。另外,對于PCT50和MobileT50這些類,坦克的功能會引起它們變化,具體平臺的變化也會引起它們變化,而我們說,一個類應該只有一個引起它變化的原因。
看上面的這個設計,對于一輛坦克,它有兩個維度的變化,一個是不同型號坦克的不同戰斗方式,一個是不同平臺的不同實現。所以這時候,我們用Bridge模式,讓型號和平臺獨立變化,不要這樣揉在一起。
![]()
如上圖,TankPlatform描述平臺, 它有一個屬性PlatformName,指平臺名稱,在PCPlatform和MobilePlatform的構造方法中將初始化這個值,它的DrawTank()和DrawShell()方法表示了不同平臺上繪制坦克和炮彈的方法,PCPlatform和MobilePlatform繼承TankPlatform,表示PC平臺和Mobile平臺。Tank有一個TankPlatform類型的protected字段platform,它表示坦克所運行的平臺,T50和T75繼承于Tank。
附上用了Bridge模式后的代碼:
Code
然后就可以在Main方法中測試一下:
Code
輸出:
PC Platform T50 Shoot
PC Platform T50 Move
Mobile Platform T75 Stop
Mobile Platform T75 Turn
這樣子的設計有什么優點呢?從效果上來看:如果我們要增加其它型號的坦克,比如T80,那我們只要寫一個T80繼承Tank,實現它的4個功能即可,不需要再在T80中摻入任何平臺相關的東西,而當我們要增加其它平臺時,我們也只要寫一個具體平臺類繼承TankPlatform,也不需要重新寫射擊、轉彎等方法。這樣一來,平臺和坦克功能之間的耦合度就低得多了,也不會違背單一職責的原則了。
現在再來看我們的Bridge模式,它讓前面說的兩維度的變化各自變去,讓它們不揉在一起了。而對于Bridge模式的名字“Bridge”的起源,也許就是因為它作為這多維度之間聯系的橋梁吧,比如例子中Tank的platform字段就是這個bridge(橋)。同時,我們也可以看到對象組合的應用是很廣泛的。
小感觸
自從開始看設計模式之后,我才發現原來編程可以這么藝術,我也發覺自己當初有多么愚昧,以為軟件的核心就是算法。雖然我不是很聰明,沒有太多的天賦,但我相信,努力一定會有收獲的。同時還要感謝李建忠老師的設計模式WebCast,是它讓我第一次意識到我從前寫的程序有多么弱智(盡管我現在的程序還是很弱智,但至少比起以前好多了
)。
Bidge模式,是為了應對多維度的變化的情況,先不管那么多,例子先上。
假設現在要開發一個平常玩的那種坦克游戲,但這個游戲要有兩個版本,PC版的和手機版的,其中坦克有許多型號,但PC版所有的坦克,手機版中也要有,而且功能要完全相同的,要不然就太不公平,玩的沒意思了,但是PC版和手機版的實現肯定是有所不同的,硬件性能相差那么大,PC版的坦克外觀可能會是非常逼真的3D效果,但手機版的可能只是二維的。
于是,我就畫出了下面這張圖:

實現代碼:
這么做乍看起來是挺合理的,但是,如果我們要再加一個型號T80呢?那還要再來一個T80繼承Tank,PCT80和MobileT80再繼承T80,如果要增加很多的型號,那我們就要這么寫很多個類,更關鍵的是,PC平臺和Mobile平臺上的坦克的功能是完全一樣的,比如他們的發炮方法,轉彎方法,所以,我們在PCT50和MobileT50中難免會有重復的代碼,PCT75和MobileT75中也會有,那我們不是可以拷貝代碼嗎?當然可以,但這絕對不是好辦法,而且當我們要增加其它的平臺,那工作量又得大增。另外,對于PCT50和MobileT50這些類,坦克的功能會引起它們變化,具體平臺的變化也會引起它們變化,而我們說,一個類應該只有一個引起它變化的原因。
看上面的這個設計,對于一輛坦克,它有兩個維度的變化,一個是不同型號坦克的不同戰斗方式,一個是不同平臺的不同實現。所以這時候,我們用Bridge模式,讓型號和平臺獨立變化,不要這樣揉在一起。

如上圖,TankPlatform描述平臺, 它有一個屬性PlatformName,指平臺名稱,在PCPlatform和MobilePlatform的構造方法中將初始化這個值,它的DrawTank()和DrawShell()方法表示了不同平臺上繪制坦克和炮彈的方法,PCPlatform和MobilePlatform繼承TankPlatform,表示PC平臺和Mobile平臺。Tank有一個TankPlatform類型的protected字段platform,它表示坦克所運行的平臺,T50和T75繼承于Tank。
附上用了Bridge模式后的代碼:
然后就可以在Main方法中測試一下:
輸出:
PC Platform T50 Shoot
PC Platform T50 Move
Mobile Platform T75 Stop
Mobile Platform T75 Turn
這樣子的設計有什么優點呢?從效果上來看:如果我們要增加其它型號的坦克,比如T80,那我們只要寫一個T80繼承Tank,實現它的4個功能即可,不需要再在T80中摻入任何平臺相關的東西,而當我們要增加其它平臺時,我們也只要寫一個具體平臺類繼承TankPlatform,也不需要重新寫射擊、轉彎等方法。這樣一來,平臺和坦克功能之間的耦合度就低得多了,也不會違背單一職責的原則了。
現在再來看我們的Bridge模式,它讓前面說的兩維度的變化各自變去,讓它們不揉在一起了。而對于Bridge模式的名字“Bridge”的起源,也許就是因為它作為這多維度之間聯系的橋梁吧,比如例子中Tank的platform字段就是這個bridge(橋)。同時,我們也可以看到對象組合的應用是很廣泛的。
小感觸
自從開始看設計模式之后,我才發現原來編程可以這么藝術,我也發覺自己當初有多么愚昧,以為軟件的核心就是算法。雖然我不是很聰明,沒有太多的天賦,但我相信,努力一定會有收獲的。同時還要感謝李建忠老師的設計模式WebCast,是它讓我第一次意識到我從前寫的程序有多么弱智(盡管我現在的程序還是很弱智,但至少比起以前好多了



}
}
浙公網安備 33010602011771號