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

C# 設計模式深度剖析:橋接模式 - 讓抽象與實現獨立演化

     編輯:關於C語言

前言:繼承爆炸的噩夢與解藥

若直接用繼承建模「品牌 x 功能」的矩陣:`ChangHongRemote`、`ChangHongAdvancedRemote`、`SamsungRemote`、`SamsungAdvancedRemote`... 每新增一品牌或一功能,類別數呈乘法增長。橋接模式將抽象化 (遙控器介面)與實現化 (電視機具體操作)分離,雙方透過組合關係協作,實現獨立演化。

一、 經典範例:萬用遙控器控制多品牌電視

橋接模式類圖 - 遙控器與電視

1. 實現化維度:電視機抽象與具體品牌

// 實現化介面
public interface ITV
{
    void On();
    void Off();
    void TuneChannel();
}

// 具體實現:長虹
public class ChangHongTV : ITV
{
    public void On() => Console.WriteLine("長虹電視:開機歡迎畫面");
    public void Off() => Console.WriteLine("長虹電視:關機待機");
    public void TuneChannel() => Console.WriteLine("長虹電視:切換頻道中...");
}

// 具體實現:三星
public class SamsungTV : ITV
{
    public void On() => Console.WriteLine("三星電視:Smart Hub 啟動");
    public void Off() => Console.WriteLine("三星電視:進入省電模式");
    public void TuneChannel() => Console.WriteLine("三星電視:數位頻道搜尋...");
}

2. 抽象化維度:遙控器基類與功能擴展

// 抽象化基類:持有實現化參考
public abstract class RemoteControl
{
    protected ITV _tv;

    protected RemoteControl(ITV tv) => _tv = tv;

    public virtual void On() => _tv.On();
    public virtual void Off() => _tv.Off();
    public virtual void SetChannel() => _tv.TuneChannel();
}

// 擴展抽象化:增加「音量控制」、「上一台」等高級功能
public class AdvancedRemote : RemoteControl
{
    public AdvancedRemote(ITV tv) : base(tv) { }

    public void VolumeUp() => Console.WriteLine("遙控器:音量 +");
    public void VolumeDown() => Console.WriteLine("遙控器:音量 -");
    public void PreviousChannel() => Console.WriteLine("遙控器:返回上一台");

    // 可覆寫基礎行為增加日誌、驗證等
    public override void SetChannel()
    {
        Console.WriteLine(">>> 記錄用戶換台行為");
        base.SetChannel();
        Console.WriteLine("<<< 換台完成");
    }
}

3. 客戶端:靈活組合品牌與遙控器類型

static void Main()
{
    // 組合 1:基礎遙控器 + 長虹
    RemoteControl basic = new RemoteControl(new ChangHongTV());
    basic.On();
    basic.SetChannel();
    basic.Off();

    Console.WriteLine("----- 分割線 -----");

    // 組合 2:高級遙控器 + 三星
    AdvancedRemote advanced = new AdvancedRemote(new SamsungTV());
    advanced.On();
    advanced.VolumeUp();
    advanced.PreviousChannel(); // 基礎遙控器沒有此功能
    advanced.Off();

    Console.ReadKey();
}

二、 另一視角:汽車與引擎的橋接

汽車類型 (`Bus`, `Limousine`) 與引擎類型 (`GasEngine`, `DieselEngine`) 正交變化。

// 抽象化:汽車
public abstract class Car
{
    protected IEngine _engine;
    protected Car(IEngine engine) => _engine = engine;
    public abstract void Start();
    public abstract void Stop();
}

// 擴展抽象化
public class Bus : Car
{
    public Bus(IEngine engine) : base(engine) { }
    public override void Start() { _engine.Start(); Console.WriteLine("公車啟動,準備載客"); }
    public override void Stop() { _engine.Stop(); Console.WriteLine("公車熄火,結束班次"); }
}

public class Limousine : Car
{
    public Limousine(IEngine engine) : base(engine) { }
    public override void Start() { _engine.Start(); Console.WriteLine("豪華轎車靜默啟動"); }
    public override void Stop() { _engine.Stop(); Console.WriteLine("豪華轎車平穩熄火"); }
}

// 實現化:引擎介面
public interface IEngine
{
    void Start();
    void Stop();
}

public class GasEngine : IEngine
{
    public void Start() => Console.WriteLine("汽油引擎:點火啟動");
    public void Stop() => Console.WriteLine("汽油引擎:切斷燃油");
}

public class DieselEngine : IEngine
{
    public void Start() => Console.WriteLine("柴油引擎:壓縮點火啟動");
    public void Stop() => Console.WriteLine("柴油引擎:切斷供油");
}

// 使用
var bus = new Bus(new DieselEngine());
bus.Start(); // 柴油引擎啟動 -> 公車啟動
var limo = new Limousine(new GasEngine());
limo.Start(); // 汽油引擎啟動 -> 豪華轎車啟動

三、 模式核心解析

角色範例對應職責
Abstraction (抽象化)RemoteControl, Car定義高層介面,持有 Implementor 參考
RefinedAbstraction (修正抽象化)AdvancedRemote, Bus擴展介面,增加新功能
Implementor (實現化)ITV, IEngine定義底層操作介面
ConcreteImplementor (具體實現化)ChangHongTV, GasEngine實作底層具體邏輯

關鍵優勢

  • 分離介面與實現:抽象化不再綁定固定實現,可動態切換 (如運行時換電視品牌)。
  • 避免繼承爆炸:M 個抽象 x N 個實現 = M + N 個類別,而非 M x N。
  • 符合開放-封閉原則:新增品牌只加 ConcreteImplementor;新增遙控功能只加 RefinedAbstraction,互不影響。
  • 隱藏實現細節:客戶端只操作遙控器,不知電視內部電路邏輯。

適用場景

  • 系統有多個正交變化維度 (如:UI 主題 x 平台、資料庫驅動 x SQL 方言、訊息發送 x 序列化格式)。
  • 不希望使用繼承造成類別膨脹,或需在運行時動態綁定實現。
  • 經典應用:JDBC 驅動、集合框架 (`List` 介面 vs `ArrayList`/`LinkedList`)、.NET Provider Model。

四、 .NET 框架中的橋接身影

  • Stream 抽象與具體流:`Stream` (抽象化) 定義讀寫介面;`FileStream`、`MemoryStream`、`NetworkStream`、`CryptoStream` (具體實現化) 處理不同儲存媒介。`BufferedStream`、`CryptoStream` 更是裝飾器+橋接混合。
  • DbProviderFactory:抽象工廠建立橋接的連線/命令/適配器家族。
  • WPF/XAML:控制項邏輯 (抽象) 與渲染視覺樹 (實現) 分離。

五、 總結

橋接模式以「組合取代繼承」,將「做什麼」 (抽象化) 與「怎麼做」 (實現化) 解耦。它是處理多維度變化系統的基石模式,雖增加了設計複雜度 (需識別兩條變化軸),但換來的是系統級的靈活性與可維護性。識別出系統中**穩定的高層抽象**與**易變的底層實現**,是套用此模式的關鍵洞察力。

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