一句話解釋:
兩個無關聯的類,通過實現同一介面或繼承對方得到新的介面卡類,新的介面卡類中通過實現原本類的操作,可達到進行相同的操作的目的。
介面卡模式(Apapter Pattern)是一種結構型設計模式,用於將一個類的實現轉換成使用者端所期望的另一個類,這個類中的操作和目標類具有相同的操作,以達到兩個不相關的類可以互操作的目的。
官方意圖:將一個類的介面轉換成客戶希望的另外一個介面。使得原本由於介面不相容而不能一起工作的那些類可以一起工作。
一個比喻:(兩位來自不同方言區的學生)
分別來自廣州和海口的兩位同學,如果都各自說自己的家鄉話粵語和海南話,則根本無法溝通,此時普通話就是一個介面卡,將兩種方言翻譯成普通話來進行適配,這樣就可以順暢溝通了。
優缺點:
適用場景:
實際使用場景舉例:
下面是一個使用介面卡設計模式的範例,假設我們有一個電源插座介面 ISocket,其中定義了供電方法 SupplyPower():
class Program // 測試
{
static void Main(string[] args)
{
// 國標插座
ChinaSocket chinaSocket = new ChinaSocket();
ChinaSocketAdapter chinaAdapter = new ChinaSocketAdapter(chinaSocket);
Laptop laptop1 = new Laptop(chinaAdapter); // 筆電1 通過國標版插座充電
laptop1.Charge();
// 美版插座
USASocket usaSocket = new USASocket();
USASocketAdapter usaAdapter = new USASocketAdapter(usaSocket);
Laptop laptop2 = new Laptop(usaAdapter); // 同一型別的筆電2 通過美標版插座充電
laptop2.Charge();
Console.ReadKey();
}
}
// 電源插座介面
public interface ISocket
{
void SupplyPower();
}
// 國標版插口
public class ChinaSocket
{
public string name { get; set; }
public void Charge()
{
Console.WriteLine("開始充電!");
}
}
// 美版插口
public class USASocket
{
public string name { get; set; }
public void PowerUp()
{
Console.WriteLine("Start charging!");
}
}
// 國標版的介面卡,實現統一的電源插座介面
public class ChinaSocketAdapter : ISocket
{
private readonly ChinaSocket _chinaSocket;
public ChinaSocketAdapter(ChinaSocket chinaSocket)
{
_chinaSocket = chinaSocket;
}
public void SupplyPower() // 國標版實現充電方法,呼叫特有的 Charge() 方法
{
_chinaSocket.Charge();
}
}
// 美版插座介面卡,實現統一的插座介面
public class USASocketAdapter : ISocket
{
private readonly USASocket _usaSocket;
public USASocketAdapter(USASocket usaSocket)
{
_usaSocket = usaSocket;
}
public void SupplyPower() // 美版實現充電方法,呼叫特有的 PowerUp() 方法
{
_usaSocket.PowerUp();
}
}
// 筆記型電腦類實現,統一充電方法 Charge()
public class Laptop
{
private readonly ISocket _socket;
public Laptop(ISocket socket)
{
_socket = socket;
}
public void Charge()
{
_socket.SupplyPower();
}
}
最終,無論是國標還是美版的插座,均呼叫 Charge() 方法進行充電,充當介面卡角色的就是電源插座介面 IScoket。
如下簡單畫一下上一章節範例程式碼對應的類圖:(美版相似就省略了,只顯示國標版)
Client:給 Laptop 宣告插座並完成充電動作。
Laptop:定義統一充電介面的模板,供介面卡實現。
ChinaSocketAdapter:對 ChinaSocket 類和 Laptop 進行適配。
ChinaSocket:已存在的類,此類需要適配。
IDataAdapter 介面的實現類通常是資料庫存取器,它們提供了一種與特定資料庫型別無關的方式來存取資料。
下面是介面 IDataAdapter 的原始碼:
// System.Data.Common, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// System.Data.IDataAdapter
using System.Data;
using System.Diagnostics.CodeAnalysis;
public interface IDataAdapter
{
MissingMappingAction MissingMappingAction { get; set; }
MissingSchemaAction MissingSchemaAction { get; set; }
ITableMappingCollection TableMappings { get; }
[RequiresUnreferencedCode("IDataReader's (built from adapter commands) schema table types cannot be statically analyzed.")]
DataTable[] FillSchema(DataSet dataSet, SchemaType schemaType);
int Fill(DataSet dataSet);
IDataParameter[] GetFillParameters();
[RequiresUnreferencedCode("IDataReader's (built from adapter commands) schema table types cannot be statically analyzed.")]
int Update(DataSet dataSet);
}
具體的資料庫,均實現了 IDataAdapter 介面:
// SQL Server
public sealed class SqlDataAdapter : DbDataAdapter, IDataAdapter, IDbDataAdapter, ICloneable
{ ... }
// Oracle
[Designer("Oracle.VsDevTools.OracleVSGDataAdapterWizard, Oracle.VsDevTools, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=MSIL", typeof(IDesigner))]
[ToolboxBitmap(typeof(resfinder), "Oracle.ManagedDataAccess.src.Client.Icons.OracleDataAdapterToolBox_hc.bmp")]
[DefaultEvent("RowUpdated")]
public sealed class OracleDataAdapter : DbDataAdapter, IDbDataAdapter, IDataAdapter
{ ... }
// MySQL
[DesignerCategory("Code")]
[Designer("MySql.Data.MySqlClient.Design.MySqlDataAdapterDesigner,MySqlClient.Design")]
public sealed class MySqlDataAdapter : DbDataAdapter, IDbDataAdapter, IDataAdapter
{ ... }
通過使用 IDataAdapter 介面,我們可以編寫與特定資料庫型別無關的程式碼,而只需要關心資料集的結構和操作。這樣,我們就可以更輕鬆地更換或擴充套件我們的資料來源,而不需要修改應用程式的程式碼。同時,IDataAdapter 介面還支援資料對映和資料驗證等高階功能,使得我們可以更好地處理複雜的資料操作。
橋接模式(Bridge)的結構與物件介面卡類似,但是 Bridge 模式的出發點不同。Bridge 的目的是將介面部分和實現部分分離,從而可以對它們較為容易也相對獨立地加以改變。而 Adapter 則意味著改變一個已有物件的介面。
裝飾模式(Decorator)增強了其他物件的功能而同時又不改變它的介面,因此 Decorator 對應用程式的透明性比介面卡要好。結果是 Decorator 支援遞迴組合,而純粹使用介面卡是不可能實現這一點的。
代理模式(Proxy)在不改變它的介面的條件下,為另一個物件定義了一個代理。
本文來自部落格園,作者:橙子家,微訊號:zfy1070491745,有任何疑問歡迎溝通,一起成長! 您的支援,博主的動力!
轉載本文請註明原文連結:https://www.cnblogs.com/hnzhengfy/p/SJMSLL_Adapter.html