JAVA設計模式之 橋接模式【Bridge Pattern】
一、概述
將抽象部分與它的實現部分分離,使它們都可以獨立地變化。它是一種物件結構型模式,又稱為柄體(Handle and Body)模式。
二、適用場景
處理多維度變化。
業務場景:某功能為將資料庫中的資料轉換成多種檔案格式,例如txt、xml、pdf等格式,同時需要支援多種不同型別的資料庫的讀取。便可使用橋接模式對其進行設計。
這裡的維度有兩個 分別為:不同的檔案格式 和 不同的資料庫型別。如下圖:
三、UML類圖
橋接模式通用結構圖:
針對上面的業務場景-橋接模式-示例結構圖:
四、參與者
①Abstraction(抽象類):用於定義抽象類的介面,它一般是抽象類而不是介面,其中定義了一個Implementor(實現類介面)型別的物件並可以維護該物件,它與Implementor之間具有關聯關係,它既可以包含抽象業務方法,也可以包含具體業務方法。
②RefinedAbstraction(擴充抽象類):擴充由Abstraction定義的介面,通常情況下它不再是抽象類而是具體類,它實現了在Abstraction中宣告的抽象業務方法,在RefinedAbstraction中可以呼叫在Implementor中定義的業務方法。
③Implementor(實現類介面):定義實現類的介面,這個介面不一定要與Abstraction的介面完全一致,事實上這兩個介面可以完全不同,一般而言,Implementor介面僅提供基本操作,而Abstraction定義的介面可能會做更多更復雜的操作。Implementor介面對這些基本操作進行了宣告,而具體實現交給其子類。通過關聯關係,在Abstraction中不僅擁有自己的方法,還可以呼叫到Implementor中定義的方法,使用關聯關係來替代繼承關係。
④ConcreteImplementor(具體實現類):具體實現Implementor介面,在不同的ConcreteImplementor中提供基本操作的不同實現,在程式執行時,ConcreteImplementor物件將替換其父類物件,提供給抽象類具體的業務操作方法。
五、用例學習<以適用場景裡的業務場景作為程式碼設計>
1、JDBC 驅動連線管理類:JdbcDriverManager.java
/**
* JDBC 驅動連線管理類
* @author lvzb.software@qq.com
*
*/
public class JdbcDriverManager {
public String connectAndReadOracle(){
// 模擬連線Oracle資料庫的程式碼
System.out.println("已成功連線到Oracle資料庫");
// 模式 省略 從資料庫中獲取內容的程式碼
String content = "已成功從Oracle資料庫中讀取到了內容";
return content;
}
public String connectAndReadMySql(){
// 模擬連線MySql資料庫的程式碼
System.out.println("已成功連線到MySql資料庫");
// 模式 省略 從資料庫中獲取內容的程式碼
String content = "已成功從MySql資料庫中讀取到了內容";
return content;
}
public String connectAndReadSqlServer(){
// 模擬連線Sql Server資料庫的程式碼
System.out.println("已成功連線到Sql Server資料庫");
// 模式 省略 從資料庫中獲取內容的程式碼
String content = "已成功從Sql Server資料庫中讀取到了內容";
return content;
}
}
2、<角色:實現類介面> FileExportImpl.java
/**
* 獲取檔案內容、連線資料庫來源介面
* @author lvzb.software@qq.com
*
*/
public interface FileExportImpl {
/**
* 讀取資料庫中的內容
* @param jdbcDriver
* @return
*/
public String readContent();
}
3、<角色:具體實現類> FileExportFromOracle.java
/**
* 從Oracle資料庫獲取內容
* @author lvzb.software@qq.com
*
*/
public class FileExportFromOracle implements FileExportImpl {
@Override
public String readContent() {
JdbcDriverManager jdbcDriver = new JdbcDriverManager();
return jdbcDriver.connectAndReadOracle();
}
}
4、<角色:具體實現類> FileExportFromMySql.java
/**
* 從MySql資料庫獲取內容
* @author lvzb.software@qq.com
*
*/
public class FileExportFromMySql implements FileExportImpl {
@Override
public String readContent() {
JdbcDriverManager jdbcDriver = new JdbcDriverManager();
return jdbcDriver.connectAndReadMySql();
}
}
5、<角色:具體實現類> FileExportFromSqlServer.java
/**
* 從Sql Server資料庫獲取內容
* @author lvzb.software@qq.com
*
*/
public class FileExportFromSqlServer implements FileExportImpl {
@Override
public String readContent() {
JdbcDriverManager jdbcDriver = new JdbcDriverManager();
return jdbcDriver.connectAndReadSqlServer();
}
}
6、<角色:抽象類> FileExportAbstraction.java
/**
* 檔案格式匯出 抽象類
* @author lvzb.software@qq.com
*
*/
public abstract class FileExportAbstraction {
protected FileExportImpl fileSouce;
public void setFileSource(FileExportImpl fileSouce){
this.fileSouce = fileSouce;
}
public abstract void exportFile();
}
7、<角色:擴充抽象類> TxtFileExport.java
/**
* Txt檔案格式匯出具體類
* @author lvzb.software@qq.com
*
*/
public class TxtFileExport extends FileExportAbstraction {
@Override
public void exportFile() {
String readContent = fileSouce.readContent();
System.out.println(readContent + ",將內容匯出為.txt格式");
}
}
8、<角色:擴充抽象類> XmlFileExport.java
/**
* xml檔案格式匯出具體類
* @author lvzb.software@qq.com
*
*/
public class XmlFileExport extends FileExportAbstraction {
@Override
public void exportFile() {
String readContent = fileSouce.readContent();
System.out.println(readContent + ",將內容匯出為.xml格式");
}
}
9、<角色:擴充抽象類> PdfFileExport.java
/**
* pdf檔案格式匯出具體類
* @author lvzb.software@qq.com
*
*/
public class PdfFileExport extends FileExportAbstraction {
@Override
public void exportFile() {
String readContent = fileSouce.readContent();
System.out.println(readContent + ",將內容匯出為.pdf格式");
}
}
10、客戶端測試類: Client.java
public class Client {
public static void main(String[] args) {
FileExportImpl fileOracle = new FileExportFromOracle();
FileExportImpl fileMySql = new FileExportFromMySql();
FileExportImpl fileSqlServer = new FileExportFromSqlServer();
FileExportAbstraction fileTxtExport = new TxtFileExport();
FileExportAbstraction fileXmlExport = new XmlFileExport();
FileExportAbstraction filePdfExport = new PdfFileExport();
// 如果我們要從Oracle中匯出xml格式的資料
fileXmlExport.setFileSource(fileOracle);
fileXmlExport.exportFile();
System.out.println("--------------------\n");
// 如果我們要從Oracle中匯出txt格式的資料
fileTxtExport.setFileSource(fileOracle);
fileTxtExport.exportFile();
System.out.println("--------------------\n");
// 如果我們要從MySql中匯出pdf格式的資料
filePdfExport.setFileSource(fileMySql);
filePdfExport.exportFile();
}
}
11、執行結果 如下:
已成功連線到Oracle資料庫
已成功從Oracle資料庫中讀取到了內容,將內容匯出為.xml格式
--------------------
已成功連線到Oracle資料庫
已成功從Oracle資料庫中讀取到了內容,將內容匯出為.txt格式
--------------------
已成功連線到MySql資料庫
已成功從MySql資料庫中讀取到了內容,將內容匯出為.pdf格式
12、後續系統擴充套件
①、現如果需求要求新增加一種檔案輸入格式 如:html格式
則只需新寫一個FileExportAbstraction抽象類的子類 用以輸出html格式即可,而不需要修改其他任何類、不需要修改另一維度的程式碼。
②、現如果需求要求新增加一型別資料庫型別 如:Sybase
則只需新寫一個FileExportImpl介面的實現類、用以從Sybase資料庫中獲取內容、並修改JdbcDriverManager.java類、新增對Sybase資料庫的連線和訪問。
由此可見 在兩個變化維度中任意擴充套件一個維度,都不需要修改原有系統、提高了系統的擴充套件性和可維護性。
六、其他
主要優點:
(1)分離抽象介面及其實現部分。橋接模式使用“物件間的關聯關係”解耦了抽象和實現之間固有的繫結關係,使得抽象和實現可以沿著各自的維度來變化。所謂抽象和實現沿著各自維度的變化,也就是說抽象和實現不再在同一個繼承層次結構中,而是“子類化”它們,使它們各自都具有自己的子類,以便任何組合子類,從而獲得多維度組合物件。
(2)在很多情況下,橋接模式可以取代多層繼承方案,多層繼承方案違背了“單一職責原則”,複用性較差,且類的個數非常多,橋接模式是比多層繼承方案更好的解決方法,它極大減少了子類的個數。
(3)橋接模式提高了系統的可擴充套件性,在兩個變化維度中任意擴充套件一個維度,都不需要修改原有系統,符合“開閉原則”。
相關文章
- C#設計模式-橋接模式(Bridge Pattern)C#設計模式橋接
- C#設計模式(8)——橋接模式(Bridge Pattern)C#設計模式橋接
- 設計模式 | 橋接模式(bridge)設計模式橋接
- c++涉及模式 橋接模式(bridge Pattern)C++模式橋接
- 《設計模式》 - 6. 橋接模式( Bridge )設計模式橋接
- C#設計模式系列:橋接模式(Bridge)C#設計模式橋接
- 設計模式--橋接模式Bridge(結構型)設計模式橋接
- 設計模式(五)橋接模式Bridge == Pointer To Implementation設計模式橋接
- Java設計模式之(六)——橋接模式Java設計模式橋接
- 橋接模式(Bridge)橋接模式
- Java設計模式-橋接模式Java設計模式橋接
- 設計模式的征途—8.橋接(Bridge)模式設計模式橋接
- 設計模式之橋接模式設計模式橋接
- 設計模式之【橋接模式】設計模式橋接
- 設計模式 - Bridge 橋模式設計模式
- Java設計模式(7)----------橋接模式Java設計模式橋接
- PHP 設計模式之橋接模式PHP設計模式橋接
- 設計模式之橋接設計模式橋接
- java設計模式之一 橋接模式Java設計模式橋接
- Java橋模式(Bridge模式)Java模式
- Android設計模式之橋接模式Android設計模式橋接
- 我學設計模式 之 橋接模式設計模式橋接
- 設計模式-橋接模式設計模式橋接
- 設計模式:橋接模式設計模式橋接
- 我所理解的設計模式(C++實現)——橋模式(Bridge Pattern)設計模式C++
- 小白設計模式:橋接模式設計模式橋接
- 設計模式(八)——橋接模式設計模式橋接
- javascript設計模式橋接模式JavaScript設計模式橋接
- 設計模式(十二):橋接模式設計模式橋接
- 設計模式(十三)----結構型模式之橋接模式設計模式橋接
- (精華)2020年8月28日 二十三種設計模式(七)-橋接模式(Bridge Pattern)設計模式橋接
- 跟著GPT學設計模式之橋接模式GPT設計模式橋接
- JAVA設計模式之 代理模式【Proxy Pattern】Java設計模式
- GoLang設計模式19 - 橋接模式Golang設計模式橋接
- 9.設計模式-橋接模式設計模式橋接
- 極簡設計模式-橋接模式設計模式橋接
- Python設計模式-橋接模式Python設計模式橋接
- 大話設計模式—橋接模式設計模式橋接