1. 程式人生 > >橋接模式和策略模式的區別

橋接模式和策略模式的區別

  學習的過程中發現這兩個概念真的是有點區分不開,儘管可以很感性的說bridge模式要比strategy模式更復雜更具可塑性,更“高階”,但是如何清晰闡述兩者區別,卻實是有點困難。

套用偉人的一句話,站在巨人的肩膀上看得更遠,下邊三段分別來自CSDN論壇的貼子和一篇blogjava的文章,看了之後令我茅塞頓開,為表尊重不在冗述,直接貼原文了。

實際上所有模式可以只分為類模式和物件模式兩種,類模式是用繼承而物件模式是用委託Bridge模式和Strategy模式相似就是因為他們都將任務委託給了另外一個介面的具體實現,他們之間的區別在於Bridge的目的是讓底層實現和上層介面可以分別演化,從而提高移植性而Strategy的目的是將複雜的演算法封裝起來,從而便於替換不同的演算法。因此可以想象一般情況下Bridge的實現幾乎不會在執行時更改而Strategy的演算法則很有可能需要在執行時更換,這就導致在細節方面需要考慮的因素可能會很不相同。

strategy模式是為了擴充套件和修改,並提供動態配置。它往往可以在同一環境當中使用不同的策略,就是呼叫不同的派生類。其內部實現是自由的,不受已有的類介面的限制(很多時候根本就不呼叫現成的介面)。bridge模式是往往是為了利用已有的方法或類。它將原來不統一,不相容的介面封裝起來,變成統一的介面。它的應用往往是不同的環境或平臺下只能選擇一 種,比如說在windows平臺下只能用WinClass,而在unix平臺下只能用UnixClass.它的主要作用不是配置而是定義通用介面。

據個例子來說:我要畫園,要實心園,我可以用SolidPen來配置,畫虛線園可以用dashedPen來配置。這是strategy模式。而同樣是畫園,我是在windows下來畫實心園,就用windowPen+solidPen來配置,在unix下畫實心園就用 unixPen+solidPen來配置。如果要再windows下畫虛線園,就用windowsPen+dashedPen來配置,要在unix下畫虛 線園,就用unixPen+dashedPen來配置。

我這裡僅僅是就一種情況來說strategy和bridge的組合應用,其他的組合可能性隨環境變化而多種多樣。從中可以看出,bridge和strategy是可能組合使用,側重不同方面的。模式某種角度上來講就是物件組合。不要看他們都是物件組合就好像是一樣的。模式的動機,意圖,使用場合,組合方式,這些都是模式的一部分。其中細微的不同足以區分不同的模式。

橋接(Bridge)模式是結構型模式的一種,而策略(strategy)模式則屬於行為模式。以下是它們的UML結構圖。

在橋接模式中,Abstraction通過聚合的方式引用Implementor。

從橋接模式與策略模式談起 - 一半是火焰,一半是海水 - BlogJava - silence - 守望者

在策略模式中,Context也使用聚合的方式引用Startegy抽象介面。

從橋接模式與策略模式談起 - 一半是火焰,一半是海水 - BlogJava - silence - 守望者

從他們的結構圖可知,在這兩種模式中,都存在一個物件使用聚合的方式引用另一個物件的抽象介面的情況,而且該抽象介面的實現可以有多種並且可以替換。可以說兩者在表象上都是呼叫者與被呼叫者之間的解耦,以及抽象介面與實現的分離。

那麼兩者的區別體現在什麼地方呢?

1. 首先,在形式上,兩者還是有一定區別的,對比兩幅結構圖,我們可以發現,在橋接模式中不僅Implementor具有變化 (ConcreateImplementior),而且Abstraction也可以發生變化(RefinedAbstraction),而且兩者的變化 是完全獨立的,RefinedAbstraction與ConcreateImplementior之間鬆散耦合,它們僅僅通過Abstraction與 Implementor之間的關係聯絡起來。而在策略模式中,並不考慮Context的變化,只有演算法的可替代性。

2. 其次在語意上,橋接模式強調Implementor介面僅提供基本操作,而Abstraction則基於這些基本操作定義更高層次的操作。而策略模式強調 Strategy抽象介面的提供的是一種演算法,一般是無狀態、無資料的,而Context則簡單呼叫這些演算法完成其操作。

3. 橋接模式中不僅定義Implementor的介面而且定義Abstraction的介面,Abstraction的介面不僅僅是為了與 Implementor通訊而存在的,這也反映了結構型模式的特點:通過繼承、聚合的方式組合類和物件以形成更大的結構。在策略模式中,Startegy 和Context的介面都是兩者之間的協作介面,並不涉及到其它的功能介面,所以它是行為模式的一種。行為模式的主要特點就是處理的是物件之間的通訊方 式,往往是通過引入中介者物件將通訊雙方解耦,在這裡實際上就是將Context與實際的演算法提供者解耦。

所以相對策略模式,橋接模式要表達的內容要更多,結構也更加複雜。橋接模式表達的主要意義其實是介面隔離的原則,即把本質上並不內聚的兩種體系區別 開來,使得它們可以鬆散的組合,而策略在解耦上還僅僅是某一個演算法的層次,沒有到體系這一層次。從結構圖中可以看到,策略的結構是包容在橋接結構中的,橋 接中必然存在著策略模式,Abstraction與Implementor之間就可以認為是策略模式,但是橋接模式一般Implementor將提供一系 列的成體系的操作,而且Implementor是具有狀態和資料的靜態結構。而且橋接模式Abstraction也可以獨立變化。



舉一個例子:
策略模式:我要畫圓,要實心圓,我可以用solidPen來配置,畫虛線圓可以用dashedPen來配置。這是strategy模式。
橋接模式:同樣是畫圓,我是在windows下來畫實心圓,就用windowPen+solidPen來配置,在unix下畫實心圓就用unixPen+solidPen來配置。如果要再windows下畫虛線圓,就用windowsPen+dashedPen來配置,要在unix下畫虛線圓,就用unixPen+dashedPen來配置。
畫圓方法中,策略只是考慮演算法的替換,而橋接考慮的則是不同平臺下需要呼叫不同的工具,介面只是定義一個方法,而具體實現則由具體實現類完成。

區別:

橋接模式:不僅Implementor具有變化(ConcreteImplementor),而且Abstraction也可以發生變化(RefinedAbstraction),而且兩者的變化是完全獨立的,RefinedAbstraction與ConcreateImplementor之間鬆散耦合,它們僅僅通過Abstraction與Implementor之間的關係聯絡起來。強調Implementor介面僅提供基本操作,而Abstraction則基於這些基本操作定義更高層次的操作。
策略模式:並不考慮Context的變化,只有演算法的可替代性。強調Strategy抽象介面的提供的是一種演算法,一般是無狀態、無資料的,Context簡單呼叫這些演算法完成其操作。

所以相對策略模式,橋接模式要表達的內容要更多,結構也更加複雜。
橋接模式表達的主要意義其實是介面隔離的原則,即把本質上並不內聚的兩種體系區別開來,使得它們可以鬆散的組合,而策略在解耦上還僅僅是某一個演算法的層次,沒有到體系這一層次。
從結構圖中可以看到,策略模式的結構是包容在橋接模式結構中的,Abstraction與Implementor之間就可以認為是策略模式,但是橋接模式一般Implementor將提供一系列的成體系的操作,而且Implementor是具有狀態和資料的靜態結構。而且橋接模式Abstraction也可以獨立變化。

具體我還是覺得通過例子好理解一點,還有一句經典的話:自然流露到高內聚,低耦合才是真。 Have a nice day~

原文地址:http://hi.baidu.com/%C7%C7%C4%BE%BA%CD%D0%A1%C7%C7/blog/item/2b22631d0a2c13c3a6866904.html