設計模式之橋接模式
Intro
橋接模式(Bridge),將抽象部分與它的實現部分分離,使得它們都可以獨立地變化。
這裏說到抽象與它的實現分離指的是抽象類和它的派生類用來實現自己的對象
還有另外一種理解方式,一個類存在兩個(或多個)獨立變化的維度,我們通過組合的方式,讓這兩個(或多個)維度可以獨立進行擴展。
通過組合關係來替代繼承關係,避免繼承層次的指數級爆炸。這種理解方式非常類似於,我們之前講過的“組合優於繼承”設計原則。
Sample
internal abstract class Implementor
{
public abstract void Operation();
}
internal class ConcreteImplementorA : Implementor
{
public override void Operation()
{
Console.WriteLine("ImplementorA Operation");
}
}
internal class ConcreteImplementorB : Implementor
{
public override void Operation()
{
Console.WriteLine("ImplementorB Operation");
}
}
internal abstract class Abstraction
{
protected Implementor Implementor;
public void SetImplementor(Implementor implementor)
{
Implementor = implementor;
}
public abstract void Operation();
}
internal class RefinedAbstraction : Abstraction
{
public override void Operation()
{
Implementor.Operation();
Console.WriteLine("Invoke in RefinedAbstraction");
}
}
Abstraction ab = new RefinedAbstraction();
ab.SetImplementor(new ConcreteImplementorA());
ab.Operation();
ab.SetImplementor(new ConcreteImplementorB());
ab.Operation();
More
王爭在他的極客專欄中以 jdbc 的實現舉例說明橋接模式
我覺得 ADO.NET 中也有類似的設計,於是看了看 ADO.NET 的部分源碼,與君分享一下
ADO.NET 是 .NET 裏類似於 JDBC 用來進行數據庫操作一套抽象 API,
而 JDBC 裏的各種 driver 是用來連接數據庫,提供數據庫操作具體實現的,.NET 與之對應的是 DbProviderFactory
實際上,JDBC 本身就相當於“抽象”。注意,這裏所說的“抽象”,指的並非“抽象類”或“接口”,而是跟具體的數據庫無關的、被抽象出來的一套“類庫”。具體的 Driver(比如,com.mysql.jdbc.Driver)就相當於“實現”。注意,這裏所說的“實現”,也並非指“接口的實現類”,而是跟具體數據庫相關的一套“類庫”。JDBC 和 Driver 獨立開發,通過對象之間的組合關係,組裝在一起。JDBC 的所有邏輯操作,最終都委託給 Driver 來執行。
ADO.NET 提供了數據庫操作的抽象,而具體的 System.SqlClient
/Microsoft.SqlClient
/MySql.Data
提供了具體的實現,ADO.NET 和 Driver 基本保持獨立開發,通過對象的組合關係組裝在一起,ADO.NET 的具體操作交由對應的實現完成。
具體實現細節可以參考文末的參考鏈接
Reference
- https://github.com/WeihanLi/DesignPatterns/tree/master/StructurePattern/BridgePattern
- https://referencesource.microsoft.com/#System.Data/fx/src/data/System/Data/Common/DbProviderFactoriesConfigurationHandler.cs,4ba4f3a32e06482d
- https://referencesource.microsoft.com/#System.Data/fx/src/data/System/Data/Common/DbProviderFactories.cs,54a4aed2ea64c166
- https://referencesource.microsoft.com/#System.Data/fx/src/data/System/Data/Common/DbProviderFactory.cs,daaf2f2e817b5fd8