設計模式相關文章html
公司茶水間不知道何時新增了一個友寶自動售貨機,裏面的飲料比外面的價格便宜不少(幾乎是半價啦)。興沖沖的去點擊金罐多加寶,價格3.5元,付錢發現沒有帶錢包,幸虧帶了手機能夠微信、支付寶、QQ支付好牛逼的自動售貨機。java
無圖無真相,下面直接上支付時候的圖設計模式
適配器模式(Adapter Pattern) :將一個接口轉換成客戶但願的另外一個接口,適配器模式使接口不兼容的那些類能夠一塊兒工做,其別名爲包裝器(Wrapper)。適配器模式既能夠做爲類結構型模式,也能夠做爲對象結構型模式。微信
適配器模式包含四個角色:app
目標接口(Target):客戶所期待的接口。目標能夠是具體的或抽象的類,也能夠是接口。ide
須要適配的類(Adaptee):須要適配的類或適配者類。微信支付
適配器(Adapter):經過包裝一個須要適配的對象,把原接口轉換成目標接口。spa
客戶類 (Client):客戶端調用設計
書上對適配器模式講了兩種類型,類適配器模式和對象適配器模式。因爲類適配器模式經過多重繼承對一個接口與另外一個接口進行匹配,而C#、java等語言都不支持多重繼承,於是這裏只是介紹對象適配器。code
基本代碼示例
/// <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)