首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 橋接模式完全指南:抽象與實現分離的雙維度擴展架構

     編輯:關於C#

前言

當系統有兩個獨立變化的維度(如:訊息操作類型:基本/進階 × 儲存方式:SQL/XML/JSON/NoSQL)時,若用繼承組合會導致類別爆炸(基本SQL、基本XML、進階SQL、進階XML...)。橋接模式將「抽象部分」與「實現部分」分離,使它們可以獨立變化:抽象層定義高層操作介面,持有實現層介面參考,委派具體工作;實現層定義底層操作介面,由具體實現類別實作。本文以訊息系統為例,展示 Message/MyMessage(抽象維度)與 SqlMessage/XmlMessage(實現維度)如何獨立擴展並自由組合。

模式結構與四大角色

  • Abstraction(抽象化):Message,定義高層操作 Get()、Insert(),持有 AbstractMessage 實現參考,委派呼叫。
  • RefinedAbstraction(修正抽象化):MyMessage,繼承 Message,擴展高層行為(如:結果後綴標記),不涉及底層儲存邏輯。
  • Implementor(實現化介面):AbstractMessage,定義底層操作 Get()、Insert() 介面。
  • ConcreteImplementor(具體實現化):SqlMessage、XmlMessage,實作具體儲存邏輯。
橋接模式類別圖

核心程式碼機制深度解析

1. 實現化介面:底層操作契約

public abstract class AbstractMessage
{
    public abstract List<MessageModel> Get();
    public abstract bool Insert(MessageModel mm);
}

2. 具體實現化:儲存邏輯封裝

public class SqlMessage : AbstractMessage
{
    public override List<MessageModel> Get()
    {
        var l = new List<MessageModel>();
        l.Add(new MessageModel("SQL方式獲取Message", DateTime.Now));
        return l;
    }
    public override bool Insert(MessageModel mm) { return true; }
}

public class XmlMessage : AbstractMessage
{
    public override List<MessageModel> Get()
    {
        var l = new List<MessageModel>();
        l.Add(new MessageModel("XML方式獲取Message", DateTime.Now));
        return l;
    }
    public override bool Insert(MessageModel mm) { return true; }
}

3. 抽象化:高層操作與委派

public class Message
{
    private AbstractMessage _abstractMessage;
    public AbstractMessage AbstractMessage 
    { 
        get { return _abstractMessage; } 
        set { _abstractMessage = value; } 
    }

    public virtual List<MessageModel> Get() => _abstractMessage.Get();
    public virtual bool Insert(MessageModel mm) => _abstractMessage.Insert(mm);
}

關鍵:抽象化「擁有」實現化(組合關係),而非「是一個」實現化(繼承關係)。

4. 修正抽象化:高層行為擴展

public class MyMessage : Message
{
    public override List<MessageModel> Get()
    {
        var l = base.Get(); // 呼叫基類委派 → 實現化.Get()
        foreach (var mm in l)
            mm.Message += "(RefinedAbstraction)"; // 高層增強:標記來源
        return l;
    }
}

5. 客戶端:自由組合兩個維度


var m = new MyMessage(); // 選擇抽象維度:進階版

m.AbstractMessage = new SqlMessage(); // 選擇實現維度:SQL
Response.Write(m.Insert(new MessageModel("插入", Now)));
Response.Write(m.Get()[0].Message); // SQL方式獲取Message(RefinedAbstraction)

m.AbstractMessage = new XmlMessage(); // 切換實現維度:XML
Response.Write(m.Insert(new MessageModel("插入", Now)));
Response.Write(m.Get()[0].Message); // XML方式獲取Message(RefinedAbstraction)

執行結果驗證

True
SQL方式獲取Message(RefinedAbstraction) 2007-5-13 19:11:19
True
XML方式獲取Message(RefinedAbstraction) 2007-5-13 19:11:19

完美驗證:抽象維度(MyMessage 增強行為)與實現維度(SQL/XML 儲存邏輯)正交組合,互不影響。

橋接模式 vs 策略模式 vs 適配器模式

維度橋接模式策略模式適配器模式
意圖分離抽象與實現,雙向獨立擴展封裝可互換演算法轉換不相容介面
關係抽象「擁有」實現(組合)Context「擁有」StrategyAdapter「包裝」Adaptee
變化維度兩個獨立維度單一演算法維度介面不匹配
客戶端感知知曉抽象與實現兩層只知 Context只知 Target 介面

進階應用與最佳實務

多維度橋接:N 個正交維度

若有 3 個維度(如:UI 主題 × 渲染引擎 × 平台),可串聯橋接:
Abstraction → ImplementorA → ImplementorB → ImplementorC
或使用「橋接的橋接」:抽象層持有多個實現介面參考。

橋接與依賴注入:天然搭檔


public class MessageAbstraction
{
    private readonly IMessageImplementor _implementor;
    public MessageAbstraction(IMessageImplementor implementor) 
        => _implementor = implementor;
    // 委派方法...
}

// DI 註冊
services.AddTransient();
services.AddTransient();
// 客戶端注入 MessageAbstraction,實現由容器決定

優點:編譯期完全解耦、測試易 Mock、執行期動態切換實現、支援多實現共存(Named Services)。

避免過度橋接

  • 若實現維度極少(1-2 種)且固定,直接繼承更簡單(YAGNI)。
  • 若抽象與實現高度耦合(抽象方法直接對應實現方法 1:1),橋接僅增加間接層。
  • 判斷標準:是否預期兩個維度**獨立擴展**且**自由組合**?

.NET 實際應用案例

  • ADO.NET Provider Model:DbConnection (Abstraction) ↔ SqlConnection/OracleConnection (Implementor),DbCommand、DbDataReader 同理。
  • Stream 抽象與實現:Stream (Abstraction) ↔ FileStream/MemoryStream/NetworkStream (Implementor),BufferedStream 為 RefinedAbstraction。
  • WPF 渲染架構:視覺樹 (Abstraction) ↔ 組合渲染器/光柵化器 (Implementor)。
  • Entity Framework Database Provider:IDatabaseProvider 介面,SQL Server/PostgreSQL/MySQL/SQLite 實現。
  • ASP.NET Core Logging:ILogger (Abstraction) ↔ ConsoleLogger/JsonLogger/EventLogLogger (Implementor)。

優缺點總結

優點

  • 分離介面與實現:抽象與實現可獨立演化、編譯、部署。
  • 避免類別爆炸:M 個抽象 × N 個實現 → M+N 個類別(而非 M×N)。
  • 符合開閉原則:新增抽象或實現無需修改既有程式碼。
  • 執行期動態切換實現:abstraction.Implementor = newImpl。
  • 隱藏實現細節:客戶端只依賴抽象層介面。

缺點

  • 增加系統複雜度:雙層介面、委派呼叫、組合管理。
  • 雙重間接層可能影響效能(通常可忽略)。
  • 設計困難:需正確識別兩個正交變化維度,誤判導致過度設計。

總結

橋接模式以「組合取代繼承」,將系統拆解為「抽象維度」與「實現維度」兩個正交層次,實現雙向獨立擴展與自由組合。本範例以 Message/MyMessage(操作層級)× SqlMessage/XmlMessage(儲存方式)為例,完整展示了抽象化委派實現化、修正抽象化增強高層行為、客戶端動態組合的核心機制。實務中,從 ADO.NET Provider、Stream 架構、EF Database Provider 到跨平台 UI 渲染、日誌輸出、訊息隊列客戶端,橋接模式是大型框架、庫、中間件實現「多實現、可插拔、可測試」架構的基石。掌握其核心——「識別正交維度、定義實現介面、抽象層委派組合、DI 容器注入」,能讓你在設計需要支援多種底層實現、多種高層功能組合的系統時,構建出極具彈性與可維護性的雙層架構。


參考資源:DoFactory Bridge Pattern

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved