Bridge Pattern(橋樑模式)

目錄

1、定義

2、類圖

3、實現

3.1 實現化角色 Implementor

3.2 具體實現化角色 ConcreteImplementor

3.3 抽象化角色 Abstraction

3.4 修正抽象化角色 RefinedAbstraction

4、優點

5、應用場景

6、注意事項

7、最佳實踐


1、定義

橋樑模式(Bridge Pattern)也叫做橋接模式,是一個比較簡單的模式,其定義如下:

  • Decouple an abstraction from its implementation so that the two can vary independently.
  • 將抽象和實現解耦,使得兩者可以獨立地變化。
  • 注:重點在解耦

2、類圖

橋樑模式的重點是在“解耦”上,如何解耦是我們要了解的重點。橋樑模式的通用類圖如下:(類間的聚合、繼承、方法重寫

橋樑模式中的4個角色:

  • Abstraction(抽象化角色):它的主要職責是定義出該角色的行爲,同時保存一個對實現化角色的引用,該角色一般
  • 是抽象類。
  • Implementor(實現化角色):它是接口或者抽象類,定義角色必需的行爲和屬性。
  • RefinedAbstraction(修正抽象化角色):它引用實現化角色對抽象化角色進行修正。
  • ConcreteImplementor(具體實現化角色):它實現接口或抽象類定義的方法和屬性。
  • 核心:抽象角色引用實現角色或者說抽象角色的部分實現是由實現角色完成的。

3、實現

3.1 實現化角色 Implementor

public interface Implementor {

    void doSomething();

    void doAnything();
}

3.2 具體實現化角色 ConcreteImplementor

public class ConcreteImplementor1 implements Implementor {
    @Override
    public void doSomething() { /*業務邏輯處理*/ }

    @Override
    public void doAnything() { /*業務邏輯處理*/ }
}

public class ConcreteImplementor2 implements Implementor {
    @Override
    public void doSomething() { /* 業務邏輯 */ }

    @Override
    public void doAnything() { /* 業務邏輯 */ }
}

上面定義了兩個具體實現化角色——代表兩個不同的業務邏輯。 

3.3 抽象化角色 Abstraction

public abstract class Abstraction {
    // 定義對實現化角色的引用
    private Implementor imp;
    // 約束子類必須實現該構造函數
    public Abstraction(Implementor _imp) {
        this.imp = _imp;
    }
    // 自身的行爲和屬性
    public void request() {
        this.imp.doSomething();
    }
    // 獲得實現化角色
    public Implementor getImp() {
        return imp;
    }
}

爲什麼要增加一個構造函數?答案是爲了提醒子類,你必須做這項工作,指定實現者,特別是已經明確了實現者,則儘量清晰明確地定義出來。 想想看,如果我們的實現化角色有很多的子接口,然後是一堆的子實現。如果在構造函數中不傳遞一個儘量明確的實現者,代碼就很不清晰。

3.4 修正抽象化角色 RefinedAbstraction

public class RefineAbstraction extends Abstraction {
    // 覆寫構造函數
    public RefineAbstraction(Implementor _imp) {
        super(_imp);
    }
    // 修正父類的行爲
    @Override
    public void request() {
        // 業務處理
        super.request();
        super.getImp().doAnything();
    }
}

4、優點

  • 抽象和實現分離:抽象和實現分離這也是橋樑模式的主要特點,它完全是爲了解決繼承的缺點而提出的設計模式。在該模式下,實現可以不受抽象的約束,不用再綁定在一個固定的抽象層次上。
  • 優秀的擴充能力:看看我們的例子,想增加實現?沒問題!想增加抽象,也沒有問題!只要對外暴露的接口層允許這樣的變化,我們已經把變化的可能性減到最小。
  • 實現細節對客戶透明:客戶不用關心細節的實現,它已經由抽象層通過聚合關係完成了封裝。

5、應用場景

  • 不希望或不適用使用繼承的場景:不希望或不適用使用繼承的場景例如繼承層次過渡、無法更細化設計顆粒等場景,需要考慮使用橋樑模式。
  • 接口或抽象類不穩定的場景:明知道接口不穩定還想通過實現或繼承來實現業務需求,那是得不償失的,也是比較失敗的做法。
  • 重用性要求較高的場景:設計的顆粒度越細,則被重用的可能性就越大,而採用繼承則受父類的限制,不可能出現太細的顆粒度。

6、注意事項

橋樑模式是非常簡單的,使用該模式時主要考慮如何拆分抽象和實現,並不是一涉及繼承就要考慮使用該模式,那還要繼承幹什麼呢?橋樑模式的意圖還是對變化的封裝,儘量把可能變化的因素封裝到最細、最小的邏輯單元中,避免風險擴散。因此我們在進行系統設計時,發現類的繼承有N層時,可以考慮使用橋樑模式。

7、最佳實踐

類的繼承特性有很多優點,那有沒有缺點呢?

強侵入,父類有一個方法,子類也必須有這個方法。這是不可選擇的,會帶來擴展性的問題。

舉個簡單的例子來說明:Father類有一個方法A,Son繼承了這個方法,然後GrandSon也繼承了這個方法,問題是突然有一天Son要重寫父類的這個方法,他敢做嗎?絕對不敢!GrandSon要用從Father繼承過來的方法A,如果你修改了,那就要修改Son和GrandSon之間的關係,那這個風險就太大了!

橋樑模式就是這一問題的解決方法,橋樑模式描述了類間弱關聯關係。繼續上面的例子,Father類完全可以把可能會變化的方法放出去,Son子類要擁有這個方法很簡單,橋樑搭過去,獲得這個方法,GrandSon也一樣,即使你Son子類不想使用這個方法也沒關係,對GrandSon不產生影響,它不是從Son中繼承來的方法!

不能說繼承不好,它非常好,但是有缺點,我們可以揚長避短,對於比較明確不發生變化的,則通過繼承來完成;若不能確定是否會發生變化的,那就認爲是會發生變化,則通過橋樑模式來解決,這纔是一個完美的世界。

 

參考:《設計模式之禪》

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