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

設計模式深度解析:適配器模式 (Adapter Pattern) 完整實戰

     編輯:關於C#

模式意圖

將類別的介面轉換為客戶期望的另一介面,使原本因介面不相容而無法合作的類別能一起工作。別名:Wrapper (包裝器)。

兩種實作形式

1. 類別適配器 - 繼承方式

  • 多重繼承 (C++) 或單繼承 + 介面實作 (C#/Java)
  • 適配器繼承 Adaptee,實作 Target
  • 可覆寫 Adaptee 行為
  • 缺點:無法適配 Adaptee 子類、無法動態切換

2. 物件適配器 - 組合方式 (推薦)

  • 適配器持有 Adaptee 參考
  • 實作 Target,委派呼叫 Adaptee
  • 可適配 Adaptee 及其所有子類 (多型)
  • 可動態切換被適配物件
  • 符合「組合優於繼承」原則

UML 結構

類別適配器:          物件適配器:
Client → Target ← Adapter → Adaptee    Client → Target ← Adapter → Adaptee
                      ↑ 繼承                  ↑ 組合
                      │                      (多型支援子類)

完整 C# 實作

核心介面與類別


public interface ITarget { void Request(); }
public class Adaptee { public void SpecificRequest() => Console.WriteLine("Hello Adaptee!!"); }

// 類別適配器
public class ClassAdapter : Adaptee, ITarget
{
    public void Request() => SpecificRequest();
}

// 物件適配器
public class ObjectAdapter : ITarget
{
    private readonly Adaptee _adaptee;
    public ObjectAdapter(Adaptee adaptee = null) => _adaptee = adaptee;
    public void Request() => _adaptee?.SpecificRequest();
}

實戰案例:整合第三方繪圖庫

情境:自有 Grapher 使用 IDrawStrategy.Draw(),第三方庫提供 IPaint.Paint() 實作 (Triangle/Circle/Square),無法修改第三方代碼。

類別適配器版 (每種形狀需一適配器)


public class TriangleDrawAdapter : Triangle, IDrawStrategy 
{ public void Draw() => Paint(); }
public class CircleDrawAdapter : Circle, IDrawStrategy 
{ public void Draw() => Paint(); }
public class SquareDrawAdapter : Square, IDrawStrategy 
{ public void Draw() => Paint(); }

物件適配器版 (單一適配器處理所有形狀)


public class DrawAdapter : IDrawStrategy
{
    private readonly IPaint _adaptee;
    public DrawAdapter(IPaint adaptee) => _adaptee = adaptee;
    public void Draw() => _adaptee?.Paint();
}

// 客戶端
var grapher = new Grapher(new DrawAdapter(new Triangle()));
grapher.DrawShape();
grapher.SetShape(new DrawAdapter(new Circle()));
grapher.DrawShape();

四語言實作對比 (C#/C++/C++/CLI/VB)

本文提供完整四語言代碼,核心差異在於:

  • C++ 類別適配器使用 private 繼承封裝 Adaptee
  • C# 類別適配器單繼承 Adaptee + 實作 ITarget
  • C++/CLI 使用 ref class 與 gcnew
  • VB 使用 Inherits + Implements

優缺點總結

類別適配器物件適配器
✓ 易覆寫 Adaptee 行為 ✓ 適配整個類別階層 (含子類)
✓ 代碼較簡潔 ✓ 執行期動態切換 Adaptee
✗ 僅適配單一具體類別 ✗ 較難覆寫 Adaptee 行為 (需先衍生再組合)
✗ 編譯期綁定,無法動態切換 ✗ 代碼稍多 (委派呼叫)

最佳實務建議

  1. 預設選擇物件適配器:彈性高、支援多型、符合設計原則。
  2. 需覆寫 Adaptee 受保護成員時:考慮類別適配器 (C++) 或先衍生 Adaptee 再組合 (C#)。
  3. 配合泛型參數化:如上篇所示,單一泛型適配器替代多個具體適配器。
  4. .NET 內建適配器:DataAdapter, HttpClientHandler, TextReader/TextWriter 皆為適配器模式應用。

結語

適配器模式是解決介面不相容的「萬能轉接頭」。掌握類別/物件兩種形式優劣、善用組合與泛型技巧,能讓你在整合第三方庫、遷移舊系統、跨平台開發時遊刃有餘。記住:介面隔離是架構長青的關鍵,適配器是介面隔離的守門員。

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