標籤:
第二十四章、橋接模式
橋接模式也稱為橋樑模式,是結構型設計模式之一。橋接模式中體現了“單一職責原則”、“開閉原則”、“裡氏替換原則”、“依賴倒置原則”等。同時它也是很實用的一種模式。
1.定義
將抽象部分與現實部分分離,使它們都可以獨立地進行變化。
2.使用情境
(1)如果一個系統需要在構建的抽象化角色和具體角色之間增加更多的靈活性,避免在兩個層次之間建立靜態繼承聯絡。
(2)對於那些不希望使用繼承或因為多層次繼承導致系統類別的個數急劇增加的系統,也可以考慮使用橋接模式。
(3)一個類存在兩個獨立變更維度,且這兩個維度都需要擴充。
3.UML類圖
(1)Abstraction:抽象部分,該類保持一個對實現部分對象的引用,抽象部分中的方法需要調用實現部分的對象來實現,該類一般為抽象類別。
(2)RefinedAbstraction:最佳化抽象部分,抽象部分的具體實現,該類一般是對抽象部分的方法進行完善和擴充。
(3)Implementor:實現部分。可以為介面或抽象類別,其方法不一定要與抽象部分中的一致,一般情況下是由現實部分提供基本操作,而抽象部分定義的則是基於實現部分這些基本操作的業務方法。
(4)ConcreteImplementorA、ConcreteImplementorB:實現部分的具體實現。完善實現部分中的方法定義的具體邏輯。
4.簡單實現
以去咖啡店喝咖啡為例,我們假定咖啡有大杯加糖、大杯不加糖、小杯加糖和小杯不加糖四種。
給咖啡添加東西的抽象類別:(Implementor)
public abstract class CoffeeAdditives { /** * 具體要往咖啡裡添加什麼東西 * * @param 具體添加的東西 */ public abstract String addSomething();}
加糖類實現:(ConcreteImplementorA)
public class Sugar extends CoffeeAdditives{ @Override public String addSomething() { return "加糖"; }}
原味類實現:(ConcreteImplementorB)
public class Ordinary extends CoffeeAdditives{ @Override public String addSomething() { return "原味"; }}
咖啡類:(Abstraction)
public abstract class Coffee{ protected CoffeeAdditives impl; public Coffee(CoffeeAdditives impl) { this.impl = impl; } /** * 咖啡具體什麼樣由子類決定 */ public abstract void makeCoffee();}
大杯咖啡:(RefinedAbstraction)
public class LargeCoffee extends Coffee{ public LargeCoffee(CoffeeAdditives impl) { super(impl); } @Override public void makeCoffee() { System.out.println("大杯的" + impl.addSomething() + "咖啡"); }}
小杯咖啡:
public class SmallCoffee extends Coffee{ public SmallCoffee(CoffeeAdditives impl) { super(impl); } @Override public void makeCoffee() { System.out.println("小杯的" + impl.addSomething() + "咖啡"); }}
調用:
public class Client { public static void main(String[] args) { //原味 Ordinary implOrdinary = new Ordinary(); //加糖 Sugar implSugar = new Sugar(); //大杯咖啡 原味 LargeCoffee largeCoffeeOrdinary = new LargeCoffee(implOrdinary); largeCoffeeOrdinary.makeCoffee(); //小杯咖啡 原味 SmallCoffee smallCoffeeOrdinary = new SmallCoffee(implOrdinary); smallCoffeeOrdinary.makeCoffee(); //大杯咖啡 加糖 LargeCoffee largeCoffeeSugar = new LargeCoffee(implSugar); largeCoffeeSugar.makeCoffee(); //小杯咖啡 加糖 SmallCoffee smallCoffeeSugar = new SmallCoffee(implSugar); smallCoffeeSugar.makeCoffee(); }}
結果:
大杯的原味咖啡小杯的原味咖啡大杯的加糖咖啡小杯的加糖咖啡
5.Android源碼中的橋接模式1.Window與WindowManager
主要代碼如下:
public abstract class Window { //部分省略 /** * Set the window manager for use by this Window to, for example, * display panels. This is <em>not</em> used for displaying the * Window itself -- that must be done by the client. * * @param wm The window manager for adding new windows. */ public void setWindowManager(WindowManager wm, IBinder appToken, String appName) { setWindowManager(wm, appToken, appName, false); } /** * Set the window manager for use by this Window to, for example, * display panels. This is <em>not</em> used for displaying the * Window itself -- that must be done by the client. * * @param wm The window manager for adding new windows. */ public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) { mAppToken = appToken; mAppName = appName; mHardwareAccelerated = hardwareAccelerated || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false); if (wm == null) { wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); } //*將Window與WindowManager綁定 mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this); } //部分省略 }
6.總結1.優點
(1)分離抽象與現實、靈活的擴充以及對客戶來說透明的實現。
(2)橋接模式可以取代多層繼承,大大減少了子類的個數。
2.缺點
不容易設計,對開發人員來說要有一定的經驗要求。理解很容易,設計卻不容易。
《Android源碼設計模式解析與實戰》讀書筆記(二十四)