《設計模式自習室》系列,顧名思義,本系列文章帶你溫習常見的設計模式。主要內容有:html
該系列會逐步更新於個人博客和公衆號(博客見文章底部),也但願各位觀衆老爺可以關注個人我的公衆號:後端技術漫談,不會錯過精彩好看的文章。java
橋接模式是軟件設計模式中最複雜的模式之一,它把事物對象和其具體行爲、具體特徵分離開來,使它們能夠各自獨立的變化。mysql
如何利用面嚮對象的技術來使得該類型可以輕鬆的沿着多個方向進行變化,而又不引入額外的複雜度?這就要使用Bridge模式。面試
就拿汽車在路上行駛的來講。即有小汽車又有公共汽車,它們都不但能在市區中的公路上行駛,也能在高速公路上行駛。這你會發現,對於交通工具(汽車)有不一樣的類型,然而它們所行駛的環境(路)也在變化,在軟件系統中就要適應兩個方面的變化?怎樣實現才能應對這種變化呢?
將抽象部分與它的實現部分分離,使它們均可以獨立地變化。它是一種對象結構型模式,又稱爲柄體(Handle and Body)模式或接口(Interface)模式。算法
若是看不懂UML類圖,能夠先粗略瀏覽下該圖,想深刻了解的話,能夠繼續谷歌,深刻學習:
sql
橋接模式類圖:數據庫
時序圖(Sequence Diagram)是顯示對象之間交互的圖,這些對象是按時間順序排列的。時序圖中顯示的是參與交互的對象及其對象之間消息交互的順序。編程
咱們能夠大體瀏覽下時序圖,若是感興趣的小夥伴能夠去深究一下:
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正是經典的橋接模式實現:
一般使用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
橋接模式的引入會增長系統的理解與設計難度,因爲聚合關聯關係創建在抽象層,要求開發者針對抽象進行設計與編程。
這兩個模式在必定程度上都是爲了減小子類的數目,避免出現複雜的繼承關係。可是它們解決的方法卻各有不一樣
共同點:
橋接和適配器都是讓兩個東西配合工做
不一樣點:
適配器:改變已有的兩個接口,讓他們相容。因此說,若是你拿到兩個已有模塊,想讓他們同時工做,那麼你使用的適配器。
橋接模式:分離抽象化和實現,使二者的接口能夠不一樣,目的是分離,可是並不修改任何接口的具體內容。若是你還什麼都沒有,可是想分開實現,那麼橋接是一個選擇。
我是一名後端開發工程師。
主要關注後端開發,數據安全,爬蟲,物聯網,邊緣計算等方向,歡迎交流。
公衆號:後端技術漫談.jpg
若是文章對你有幫助,不妨收藏,投幣,轉發,在看起來~