設計模式之橋接模式

0x01.定義與類型

  • 定義:將抽象部分與它的具體實現部分分離,使它們均可以獨立地變化。
  • 橋接模式將繼承關係轉化成關聯關係,它下降了類與類之間的耦合度,減小了系統中類的數量,也減小了代碼量。
  • 橋接模式中的所謂脫耦,就是指在一個軟件系統的抽象化和實現化之間使用關聯關係(組合或者聚合關係)而不是繼承關係,從而使二者能夠相對獨立地變化,這就是橋接模式的用意。
  • 類型:結構型
  • UML類圖

clipboard.png

  • Java實現
/**
 * 主類抽象類
 */
public abstract class Abstraction {
    /**
     * 橋接組合對象
     */
    protected Implementor implementor;

    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }

    /**
     * 操做類
     */
    public abstract void operation();
}

/**
 * 抽象接口
 */
public interface Implementor {
    void operationImpl();
}

/**
 * 實現類
 */
public class RefinedAbstraction extends Abstraction {

    public RefinedAbstraction (Implementor implementor) {
        super(implementor);
    }

    @Override
    public void operation() {
        System.out.println("操做");
        implementor.operationImpl();
    }
}

/**
 * 接口抽象實現1
 */
public class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("橋接A");
    }
}

/**
 * 接口抽象實現2
 */
public class ConcreteImplementorB implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("橋接B");
    }
}
  • 測試與應用
/**
 * 測試與應用
 */
public class Test {
    public static void main(String[] args) {

        Abstraction abstraction1 = new RefinedAbstraction(new ConcreteImplementorA());
        Abstraction abstraction2 = new RefinedAbstraction(new ConcreteImplementorB());

        abstraction1.operation();
        abstraction2.operation();
    }
}
  • 輸出結果
操做
橋接A
操做
橋接B
  • 角色介紹html

    • Abstraction:抽象類,定義其中一個維度,會組合實現類接口。
    • RefinedAbstraction:擴充抽象類,抽象類的派生類,是一個維度的具體實現。
    • Implementor:實現類接口,另外一個維度的接口。
    • ConcreteImplementor:具體實現類,另外一個維度的具體實現類。

0x02.適用場景

  • 若是一個系統須要在構件的抽象化角色和具體化角色之間增長更多的靈活性,避免在兩個層次之間創建靜態的繼承聯繫,經過橋接模式可使它們在抽象層創建一個關聯關係。
  • 一個類存在兩個(或多個)獨立變化的維度,且這兩個(或多個)維度都須要獨立進行擴展。
  • 對於那些不但願使用繼承或由於多層次繼承致使系統類的個數急劇增長的系統,橋接模式尤其適用。

0x03.優勢

  • 分離抽象部分及其具體實現部分,提升了比繼承更好的解決方案。
  • 提升了系統的可擴展性,在兩個變化維度中任意擴展一個維度,都不須要修改原有系統。
  • 實現細節對客戶透明,能夠對用戶隱藏實現細節。
  • 符合開閉原則
  • 符合合成複用原則

0x04.缺點

  • 橋接模式的引入會增長系統的理解與設計難度,因爲聚合關聯關係創建在抽象層,要求開發者針對抽象進行設計與編程。
  • 橋接模式要求正確識別出系統中兩個獨立變化的維度,所以其使用範圍具備必定的侷限性。

0x05.樣例實現

銀行有農業銀行和工商銀行等等,而帳戶有活期帳戶和死期帳戶,兩個維度很適合使用橋接模式,下面爲具體實現:
  • Java實現
/**
 * 銀行抽象類
 */
public abstract class Bank {

    protected Account account;

    public Bank(Account account) {
        this.account = account;
    }

    /**
     * 不限制方法名,但由於委派因此起的同樣
     * 不要本身都實現了,要儘可能把行爲委託給組合的類
     * @return
     */
    abstract Account openAccount();
}

/**
 * 農業銀行實現類
 */
public class ABCBank extends Bank {

    public ABCBank (Account account) {
        super(account);
    }

    @Override
    Account openAccount() {
        System.out.println("打開中國農業銀行帳號");
        account.openAccount();
        return account;
    }
}

/**
 * 工商銀行實現類
 */
public class ICBCBank extends Bank {

    public ICBCBank(Account account) {
        super(account);
    }

    @Override
    Account openAccount() {
        System.out.println("打開中國工商銀行帳號");
        account.openAccount();
        return account;
    }
}

/**
 * 銀行帳號, 橋的實現接口
 */
public interface Account {
    /**
     * 打開帳號
     * @return
     */
    Account openAccount();

    /**
     * 查看帳號類型
     */
    void showAccountType();
}

/**
 * 按期帳戶實現類
 */
public class DepositAccount implements Account {
    @Override
    public DepositAccount openAccount() {
        System.out.println("打開按期帳號");
        return new DepositAccount();
    }

    @Override
    public void showAccountType() {
        System.out.println("這是按期帳號");
    }
}

/**
 * 活期帳戶實現類
 */
public class SavingAccount implements Account {
    @Override
    public SavingAccount openAccount() {
        System.out.println("打開活期帳號");
        return new SavingAccount();
    }

    @Override
    public void showAccountType() {
        System.out.println("這是活期帳號");
    }
}
  • 測試與應用類
/**
 * 測試與應用
 */
public class Test {

    public static void main(String[] args) {
        Bank icbcBank = new ICBCBank(new DepositAccount());
        Account icbcAccount = icbcBank.openAccount();
        icbcAccount.showAccountType();

        Bank abcBank = new ABCBank(new SavingAccount());
        Account abcAccount = abcBank.openAccount();
        abcAccount.showAccountType();
    }
}
  • 輸出結果
打開中國工商銀行帳號
打開按期帳號
這是按期帳號
打開中國農業銀行帳號
打開活期帳號
這是活期帳號
  • UML類圖

clipboard.png

0x06.相關設計模式

  • 橋接模式和組合模式java

    • 組合模式強調的部分和總體的組合
    • 橋接模式是平行級別上類的組合
  • 橋接模式和適配器模式git

    • 都是爲了讓兩個東西配合工做
    • 適配器模式是改變已有的接口讓其配合工做,把目的類似,接口不一樣的類適配起來。
    • 橋接模式是分離抽象和具體實現,目的是分離,把類的抽象和具體實現分離開,在此基礎上把接口結合起來

0x07.源碼中的橋接模式

  • jdbc: Driver

0x08.源碼地址

0x09.推薦閱讀與參考

相關文章
相關標籤/搜索