何時使用bridge模式:
從設計模式書上的得知較多的應用場景有:
1.你不希望在抽象和它的實現部分之間有一個固定的綁定關係。例如這種情況可能是因爲,在程序運行時刻實現部分應可以被選擇或者切換。(一個對象的抽象對應多個行爲)
2.類的抽象以及它的實現都應該可以通過生成子類的方法加以擴充。這時Bridge模式使你可以對不同的抽象接口和實現部分進行組合,並分別對他們進行擴充(多個抽象與多個行爲對應時且可以互相配對).
3.對一個抽象的實現部分的修改應對客戶不產生影響,既客戶的代碼不必重新編譯.
上面的描述中產生了兩個概念,對象的抽象和對象的行爲,什麼是抽象,什麼是行爲?
答:個人認爲抽象是一個很有高度的描述,比如領導說我要那塊土地做開發,這就是抽象,因爲他並沒有說明是怎麼拿下那塊土地,拿土地
可以搶回來,偷回來,買回來,逼人行賄送過來等各種方法皆可,具體的實施就是行爲。上述的案例如果領導只要一塊土地,或者說領導規定只
要是土地都給我搶回來(黑社會老大0-0),那麼也就不需要bridge模式了,直接綁定死抽象和行爲既可,代碼量也會簡單很多,但是如果領導
沒有規定死拿土地的行爲,今天拿這塊地是買的,明天拿那塊地偷的,後天拿那塊地是別人行賄過來的,那麼這時候就適用適用橋接模式了,適
用上面所述的場景1。
在來一個煮咖啡的例子,假設我要煮一杯咖啡,但是咖啡種類有很多,有黑咖啡,卡布奇諾,拿鐵,同時咖啡還有中杯,大杯,小杯之分。
所以這些組合起來就有大杯黑咖啡,大杯卡布奇諾,中杯拿鐵.....如果抽象和行爲綁定死,那麼就需要根據不同的組合寫不同的子類來實現了,
這是一件很痛苦的事,因此利用bridge模式的概念,首先抽象部分可以分離出我要一杯大杯咖啡,我要一杯中杯咖啡,我要一杯小杯咖啡。行爲
方面自然是煮咖啡給客戶咯,不同種類的咖啡有不同的材料和不同的煮法,這就是分離出來的行爲,這樣我們就可以任意組合抽象和行爲之間提
供給客戶合心意的咖啡。
代碼實例:
package com.gof.chapter4.bridge.simple;
/**
* 咖啡的抽象類,其子類主要用來描述是要大杯咖啡,小杯咖啡還是中杯
* 咖啡
**/
public abstract class Coffee {
CoffeeImp coffeeImp;
public void setCoffeeImp(CoffeeImp _coffeeImp){
this.coffeeImp = _coffeeImp;
}
public CoffeeImp getCoffeeImp(){return this.coffeeImp;}
public abstract void makeCoffee();
}
package com.gof.chapter4.bridge.simple;
/**
* 煮咖啡的抽象類
*/
public abstract class CoffeeImp {
public abstract void makeCoffeeImp();
}
- Abstraction(比如上述例子中的Coffee)--定義抽象類的接口。--維護一個指向Implementor類型對象的指正.
- RefinedAbstraction(比如上述例子的SuperSizeCoffee) -- 擴充由Abstraction定義的接口
- Implementor(比如上述例子中的CoffeeImp) -- 定義實現類的接口,該接口不一定要與Abstraction的接口完全一致;事實上這兩個接口可以完全不同。一般來講,Implementor接口僅提供基本操作,而Abstraction則定義了基於這些基本操作的較高層次的操作.
- ConcreateImplementor(比如上述例子中的Cappuccino) -- 實現Implementor接口並定義它的具體實現.
我所說的有趣的事是我們可以把Abstraction理解爲定義了一個公司經理應該做的事情,而RefinedAbstraction則是對應各個級別經理他們具體做的事,而Implementor則定義了一個公司員工該做的事,ConcreateImplementor則定義了各個員工具體做的事。所以說領導說的話都是抽象的- -~~~好吧順便吐槽下,抽象的東西永遠不會錯,所以說領導說的永遠不會錯,只有下面的人理解錯了,做錯了,悲劇啊。
最後PS下:如果對象的產生複雜或者節省內存開銷可以使用到factory模式和singleton模式。這個具體自己想吧......