bridge模式-結構型模式

何時使用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();

}


--------------------------------------分割線,描述大杯,中杯的實現類---------------------
package com.gof.chapter4.bridge.simple;
public class MediumCoffee extends Coffee{
public MediumCoffee(CoffeeImp _coffeeImp){this.setCoffeeImp(_coffeeImp);}
@Override
public void makeCoffee() {
System.out.print("我要煮一杯中杯的-");
this.getCoffeeImp().makeCoffeeImp();
}
}

package com.gof.chapter4.bridge.simple;
public class SuperSizeCoffee extends Coffee {
public SuperSizeCoffee(CoffeeImp _coffeeImp){this.setCoffeeImp(_coffeeImp);}
@Override
public void makeCoffee() {
System.out.println("我要煮一杯大杯的-");
this.getCoffeeImp().makeCoffeeImp();
}
}


-------------------------------煮咖啡的實現類----------------------------------------------
package com.gof.chapter4.bridge.simple.imp;
import com.gof.chapter4.bridge.simple.CoffeeImp;
public class BlackCoffee extends CoffeeImp {
@Override
public void makeCoffeeImp() {
System.out.println("黑咖啡!");
}
}

package com.gof.chapter4.bridge.simple.imp;
import com.gof.chapter4.bridge.simple.CoffeeImp;
public class Cappuccino extends CoffeeImp {
@Override
public void makeCoffeeImp() {
// TODO Auto-generated method stub
System.out.println("卡布奇諾.");
}
}
package com.gof.chapter4.bridge.simple.imp;
import com.gof.chapter4.bridge.simple.CoffeeImp;
public class Latte extends CoffeeImp{
@Override
public void makeCoffeeImp() {
// TODO Auto-generated method stub
System.out.println("拿鐵咖啡!");
}
}
---------------------------------客戶端測試類------------------------------------------------
package com.gof.chapter4.bridge.simple;
import com.gof.chapter4.bridge.simple.imp.*;
public class Client {
public static void main(String[] ben){
Coffee coffee = new MediumCoffee(new Cappuccino());
coffee.makeCoffee();
coffee.setCoffeeImp(new BlackCoffee());
coffee.makeCoffee();
coffee.setCoffeeImp(new Latte());
coffee.makeCoffee();
}
}
輸出結果爲:
我要煮一杯中杯的-卡布奇諾.
我要煮一杯中杯的-黑咖啡!
我要煮一杯中杯的-拿鐵咖啡!
結語:寫到這裏我有想到了一個關於bridge模式有趣的地方。首先總結下bridge模式的參與者:
  • Abstraction(比如上述例子中的Coffee)--定義抽象類的接口。--維護一個指向Implementor類型對象的指正.
  • RefinedAbstraction(比如上述例子的SuperSizeCoffee) -- 擴充由Abstraction定義的接口
  • Implementor(比如上述例子中的CoffeeImp) -- 定義實現類的接口,該接口不一定要與Abstraction的接口完全一致;事實上這兩個接口可以完全不同。一般來講,Implementor接口僅提供基本操作,而Abstraction則定義了基於這些基本操作的較高層次的操作.
  • ConcreateImplementor(比如上述例子中的Cappuccino) -- 實現Implementor接口並定義它的具體實現.

我所說的有趣的事是我們可以把Abstraction理解爲定義了一個公司經理應該做的事情,而RefinedAbstraction則是對應各個級別經理他們具體做的事,而Implementor則定義了一個公司員工該做的事,ConcreateImplementor則定義了各個員工具體做的事。所以說領導說的話都是抽象的- -~~~好吧順便吐槽下,抽象的東西永遠不會錯,所以說領導說的永遠不會錯,只有下面的人理解錯了,做錯了,悲劇啊。

 

 

最後PS下:如果對象的產生複雜或者節省內存開銷可以使用到factory模式和singleton模式。這個具體自己想吧......



 



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章