現實中,手機充電器將 220V 市電轉為 5V 直流電,讓手機能安全充電。軟體開發中,當第三方庫介面與既有系統介面不匹配時,適配器模式扮演同樣角色:將一個類的介面轉換成客戶端期望的另一個介面,使原本無法協作的類能夠共同工作。

| 類型 | 核心機制 | C# 實現關鍵 | 優缺點 |
|---|---|---|---|
| 類適配器 | 多重繼承 (繼承 Adaptee + 實作 Target) | C# 不支援多重繼承類別,故 Target 必須是介面,Adaptee 可以是類別 | 可覆寫 Adaptee 行為;但受限於單繼承 |
| 物件適配器 | 組合/委派 (持有 Adaptee 參考 + 實作 Target) | Target 可為介面或抽象類別;Adaptee 為成員欄位 | 靈活適用於 Adaptee 所有子類;無法輕易覆寫 Adaptee 行為 |
客戶端 (電器) 擁有二孔插頭 (`TwoHole`),牆上插座為三孔介面 (`IThreeHole`)。適配器 (`PowerAdapter`) 橋接兩者。
// 目標介面:客戶端期望的三孔插座
public interface IThreeHole
{
void Request(); // 三孔標準方法
}
// 被適配者:現有的二孔插頭
public abstract class TwoHole
{
public void SpecificRequest()
{
Console.WriteLine("我是兩個孔的插頭,提供基本供電。");
}
}
// 類適配器:繼承 TwoHole,實作 IThreeHole
public class ClassPowerAdapter : TwoHole, IThreeHole
{
public void Request()
{
// 內部委派給被適配者的具體方法
this.SpecificRequest();
Console.WriteLine("【類適配器】轉接完成,現在提供三孔介面。");
}
}
// 客戶端測試
public static void TestClassAdapter()
{
IThreeHole adapter = new ClassPowerAdapter();
adapter.Request(); // 輸出兩行訊息
}
// 目標角色:這裡改為抽象類別,展示靈活性
public abstract class ThreeHoleBase
{
public virtual void Request() { /* 預設實作或為空 */ }
}
// 被適配者:普通類別 (不再是 abstract)
public class TwoHolePlug
{
public void SpecificRequest()
{
Console.WriteLine("我是兩個孔的插頭 (物件適配器版)。");
}
}
// 物件適配器:繼承目標,持有被適配者實例
public class ObjectPowerAdapter : ThreeHoleBase
{
private readonly TwoHolePlug _adaptee = new TwoHolePlug(); // 組合
public override void Request()
{
_adaptee.SpecificRequest(); // 委派
Console.WriteLine("【物件適配器】轉接完成,現在提供三孔介面。");
}
}
// 客戶端測試
public static void TestObjectAdapter()
{
ThreeHoleBase adapter = new ObjectPowerAdapter();
adapter.Request();
}
適配器模式是系統整合、遷移、第三方庫引入時的「萬能轉接頭」。掌握類適配器 (繼承)與物件適配器 (組合)的差異,並在 C# 單繼承語境下做正確選擇,是架構師處理介面不兼容問題的基本功。記住:**預設選組合,特殊才繼承。**