【設計模式自習室】橋接模式 Bridge Pattern:處理多維度變化

【設計模式自習室】橋接模式 Bridge Pattern:處理多維度變化

前言

《設計模式自習室》系列,顧名思義,本系列文章帶你溫習常見的設計模式。主要內容有:html

  • 該模式的介紹,包括:
  • 引子、意圖(大白話解釋)
  • 類圖、時序圖(理論規範)
  • 該模式的代碼示例:熟悉該模式的代碼長什麼樣子
  • 該模式的優缺點:模式不是萬金油,不能夠濫用模式
  • 該模式的應用案例:瞭解它在哪些重要的源碼中被使用

該系列會逐步更新於個人博客和公衆號(博客見文章底部),也但願各位觀衆老爺可以關注個人我的公衆號:後端技術漫談,不會錯過精彩好看的文章。java

系列文章回顧

  • 【設計模式自習室】開篇:爲何咱們要用設計模式?
  • 【設計模式自習室】建造者模式
  • 【設計模式自習室】原型模式
  • 【設計模式自習室】透徹理解單例模式
  • 【設計模式自習室】理解工廠模式的三種形式
  • 【設計模式自習室】適配器模式
  • 【設計模式自習室】幕後英雄:裝飾模式

結構型——橋接模式 Bridge Pattern

引子

橋接模式是軟件設計模式中最複雜的模式之一,它把事物對象和其具體行爲、具體特徵分離開來,使它們能夠各自獨立的變化。mysql

如何利用面嚮對象的技術來使得該類型可以輕鬆的沿着多個方向進行變化,而又不引入額外的複雜度?這就要使用Bridge模式。面試

就拿汽車在路上行駛的來講。即有小汽車又有公共汽車,它們都不但能在市區中的公路上行駛,也能在高速公路上行駛。這你會發現,對於交通工具(汽車)有不一樣的類型,然而它們所行駛的環境(路)也在變化,在軟件系統中就要適應兩個方面的變化?怎樣實現才能應對這種變化呢?

定義

將抽象部分與它的實現部分分離,使它們均可以獨立地變化。它是一種對象結構型模式,又稱爲柄體(Handle and Body)模式或接口(Interface)模式。算法

類圖

若是看不懂UML類圖,能夠先粗略瀏覽下該圖,想深刻了解的話,能夠繼續谷歌,深刻學習:
【設計模式自習室】橋接模式 Bridge Pattern:處理多維度變化sql

橋接模式類圖:數據庫

【設計模式自習室】橋接模式 Bridge Pattern:處理多維度變化

  • Abstraction:抽象類
  • RefinedAbstraction:擴充抽象類
  • Implementor:實現類接口
  • ConcreteImplementor:具體實現類

時序圖

時序圖(Sequence Diagram)是顯示對象之間交互的圖,這些對象是按時間順序排列的。時序圖中顯示的是參與交互的對象及其對象之間消息交互的順序。編程

咱們能夠大體瀏覽下時序圖,若是感興趣的小夥伴能夠去深究一下:
【設計模式自習室】橋接模式 Bridge Pattern:處理多維度變化segmentfault

代碼實現

代碼參考:後端

http://www.javashuo.com/article/p-kvtvozbk-na.html

咱們有不一樣的銀行(工行,農行,建行),也有不一樣的卡(儲蓄卡,信用卡),咱們將銀行和卡進行抽象。

/**
 * 銀行抽象類
 */
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();
    }
}

調用結果:

打開中國工商銀行帳號
打開按期帳號
這是按期帳號
打開中國農業銀行帳號
打開活期帳號
這是活期帳號

使用場景舉例

JDBC數據庫訪問接口API正是經典的橋接模式實現:

【設計模式自習室】橋接模式 Bridge Pattern:處理多維度變化
一般使用JDBC鏈接數據庫時,會使用以下代碼:

Class.forName("數據庫類驅動器");
Connection conn = DriverManager.getConnection("數據庫url", "用戶名", "密碼");
//.................

JDBC爲不一樣的數據庫操做提供了相同的接口,可是JDBC自己並無針對每種數據庫提供一套具體實現代碼,而是經過接口java.sql.Driver的connect方法鏈接到了不一樣的數據庫實現。

如鏈接mysql數據庫:

package com.mysql.jdbc;

public class NonRegisteringDriver implements java.sql.Driver //對java.sql.Driver接口提供了實現
{

public Connection connect(String url, Properties info)
        throws SQLException
    {
        //實現
    }

    //其餘方法
}

Java在鏈接MySQL時須要使用mysql-connector-java.jar,mysql-connector-java.jar包提供了對MySQL數據庫操做的具體實現,並經過接口Driver鏈接到了JDBC統一的api。

詳細的JDBC源碼分析能夠參考:

https://blog.csdn.net/qq_28241149/article/details/78548178

優缺點

優勢

  • 優秀的擴展能力。
  • 實現細節對客戶透明。

缺點

橋接模式的引入會增長系統的理解與設計難度,因爲聚合關聯關係創建在抽象層,要求開發者針對抽象進行設計與編程。

總結

橋接模式與裝飾模式的區別:

這兩個模式在必定程度上都是爲了減小子類的數目,避免出現複雜的繼承關係。可是它們解決的方法卻各有不一樣

  • 裝飾模式:裝飾模式把子類中比基類中多出來的部分放到單獨的類裏面,以適應新功能增長的須要,當咱們把描述新功能的類封裝到基類的對象裏面時,就獲得了所須要的子類對象,這些描述新功能的類經過組合能夠實現不少的功能組合 .
  • 橋接模式:橋接模式則把原來的基類的實現化細節抽象出來,在構造到一個實現化的結構中,而後再把原來的基類改形成一個抽象化的等級結構,這樣就能夠實現系統在多個維度上的獨立變化 。
    橋接模式和適配器模式的區別

共同點:

橋接和適配器都是讓兩個東西配合工做

不一樣點:

適配器:改變已有的兩個接口,讓他們相容。因此說,若是你拿到兩個已有模塊,想讓他們同時工做,那麼你使用的適配器。
橋接模式:分離抽象化和實現,使二者的接口能夠不一樣,目的是分離,可是並不修改任何接口的具體內容。若是你還什麼都沒有,可是想分開實現,那麼橋接是一個選擇。

參考

關注我

我是一名後端開發工程師。

主要關注後端開發,數據安全,爬蟲,物聯網,邊緣計算等方向,歡迎交流。

各大平臺均可以找到我

  • 微信公衆號:後端技術漫談
  • Github:@qqxx6661
  • CSDN:@後端技術漫談
  • 知乎:@後端技術漫談
  • 簡書:@後端技術漫談
  • 掘金:@後端技術漫談

原創博客主要內容

  • Java面試知識點複習全手冊
  • 設計模式/數據結構 自習室
  • Leetcode/劍指offer 算法題解析
  • SpringBoot/SpringCloud菜鳥入門實戰系列
  • 爬蟲相關技術文章
  • 後端開發相關技術文章
  • 逸聞趣事/好書分享/我的興趣

我的公衆號:後端技術漫談

【設計模式自習室】橋接模式 Bridge Pattern:處理多維度變化
公衆號:後端技術漫談.jpg

若是文章對你有幫助,不妨收藏,投幣,轉發,在看起來~

相關文章
相關標籤/搜索