一、前言
公司茶水間不知道什么時候新增了一個友寶自動售貨機,里面的飲料比外面的價格便宜很多(幾乎是半價啦)。興沖沖的去點擊金罐多加寶,價格3.5元,付錢發現沒有帶錢包,幸好帶了手機可以微信、支付寶、QQ支付好牛逼的自動售貨機。
無圖無真相,下面直接上支付時候的圖

二、基本概念
適配器模式(Adapter Pattern) :將一個接口轉換成客戶希望的另一個接口,適配器模式使接口不兼容的那些類可以一起工作,其別名為包裝器(Wrapper)。適配器模式既可以作為類結構型模式,也可以作為對象結構型模式。
適配器模式包含四個角色:
目標接口(Target):客戶所期待的接口。目標可以是具體的或抽象的類,也可以是接口。
需要適配的類(Adaptee):需要適配的類或適配者類。
適配器(Adapter):通過包裝一個需要適配的對象,把原接口轉換成目標接口。
客戶類 (Client):客戶端調用
書上對適配器模式講了兩種類型,類適配器模式和對象適配器模式。由於類適配器模式通過多重繼承對一個接口與另一個接口進行匹配,而C#、java等語言都不支持多重繼承,因而這里只是介紹對象適配器。
三、代碼示例
基本代碼示例
/// <summary> /// 目標抽象類角色 /// </summary> public class Target { public virtual void Request() { Console.WriteLine("This is a common request"); } } /// <summary> /// 適配者類角色 /// </summary> public class Adaptee { public void SpecificRequest() { Console.WriteLine("This is a special request."); } } /// <summary> /// 適配器角色 /// </summary> public class Adapter : Target { // 建立一個私有的Adeptee對象 private Adaptee adaptee = new Adaptee(); /// <summary> /// 通過重寫,表面上調用Request()方法,變成了實際調用SpecificRequest() /// </summary> public override void Request() { adaptee.SpecificRequest(); } } static void Main(string[] args) { // 對客戶端來說,調用的就是Target的Request() Target target = new Adapter(); target.Request(); Console.ReadKey(); }
輸出結果:This is a special request.
自動售貨機代碼示例說明適配器模式:
//目標抽象類角色:支付接口 public interface IPay { void Pay(); }
//適配者角色:支付寶支付、財付通支付、微信支付、現金支付 public class Alipay { public void Ali_Pay() { Console.WriteLine("支付寶支付"); } } public class Tenpay { public void Ten_Pay() { Console.WriteLine("QQ支付"); } } public class WeixinPay { public void Wenxin_Pay() { Console.WriteLine("微信支付"); } } public class CashPay { public void Cash_Pay() { Console.WriteLine("現金支付"); } } /// <summary> /// 適配器角色:適配支付寶支付 /// </summary> public class AliAdapter : Alipay, IPay { public void Pay() { base.Ali_Pay(); } } /// <summary> /// 適配器角色:適配財付通支付 /// </summary> public class TenAdapter : Tenpay, IPay { public void Pay() { base.Ten_Pay(); } } /// <summary> /// 適配器角色:適配微信支付 /// </summary> public class WeixinAdapter : WeixinPay, IPay { public void Pay() { base.Wenxin_Pay(); } } /// <summary> /// 適配器角色:適配現金支付 /// </summary> public class CashAdapter : CashPay, IPay { public void Pay() { base.Cash_Pay(); } } static void Main(string[] args) { //// 對客戶端來說,調用的就是Target的Request() //Target target = new Adapter(); //target.Request(); //支付寶支付 IPay alipay = new AliAdapter(); alipay.Pay(); //現金支付 IPay cashPay = new CashAdapter(); cashPay.Pay(); //財付通支付 IPay tenpay = new TenAdapter(); tenpay.Pay(); //微信支付 IPay weixinPay = new WeixinAdapter(); weixinPay.Pay(); Console.ReadKey(); }
輸入結果:

四、總結
優點:
將目標類和適配者類解耦,通過引入一個適配器類來重用現有的適配者類,而無須修改原有代碼。
增加了類的透明性和復用性,將具體的實現封裝在適配者類中,對於客戶端類來說是透明的,而且提高了適配者的復用性。
靈活性和擴展性都非常好,通過使用配置文件,可以很方便地更換適配器,也可以在不修改原有代碼的基礎上增加新的適配器類,完全符合“開閉原則”。
應用舉例:
電腦適配器
ADO.NET中的DataAdapter
五、最后上個全圖

代碼下載:https://yunpan.cn/cYDYwAJM5KBCw (提取碼:2656)
