想象這樣一個場景,原專案中介面返回的資料是XML格式的資料,但現在來了一個新客戶,它期望介面返回的資料型別為json格式的。
想要實現要麼就是改原有介面,但這樣就違反了開閉原則,容易出現未知bug,影響到老客戶的正常使用。
而如果寫一個介面卡類也就是轉換類(第三方類),將原本返回的XML格式資料轉換成json格式資料,而具體資料是怎麼來的則直接用原有介面方法就可以。
新客戶只需要呼叫介面卡類就可以了,而老客戶這邊也不會進行任何修改處理。
如果再有新的客戶要求其他型別的返回,只需要在介面卡類中增加相應的轉換處理就可以了。
再思考一個問題,現實生活中空調插頭一般都是三頭的,但如果家裡只有兩孔插座,那必然是插不進去的。
以前老的辦法那就是把三頭插座掰掉一個,另外兩個也掰直,這樣做存在很大的安全隱患,而且有時並不能工作。
而如果提供一個擁有三孔插座和兩頭插頭的轉換器的話,那空調可以先插在這個轉換器上,然後這個轉換器再插在插座上就可以了。
本質並沒有變,只是將二孔插座包裝了一下,向外界提供了一個三孔插座的外觀以供客戶使用。
適配的本質就是轉換,將不滿足使用條件的東西通過第三方類進行加工處理成可使用的東西。
介面卡模式(Apapter Pattern)是一種結構型設計模式,將一個類的介面轉換成客戶希望的另一個介面。介面卡模式使得原本由於介面相容而不能一起工作的那些類可以一起工作。
介面卡模式用來解決現有物件與使用者端期待介面不一致的問題。
系統需要複用現有類,但是介面又與複用環境要求不一致的情況。
介面卡模式有兩種實現結構,物件介面卡和類介面卡。
試想一下,目前有一個三頭插頭的空調,需要一個三孔插座,但目前只有一個兩孔插座。
編寫一個介面卡來包裝一下這個兩孔插座,讓使用者可以使用這個空調。
類介面卡
1 /// <summary> 2 /// 兩孔插座---被適配者 3 /// </summary> 4 public class TwoHoleSocket 5 { 6 public void SpecificRequest() 7 { 8 Console.WriteLine("兩孔插座"); 9 } 10 } 11 12 /// <summary> 13 /// 三孔插座---目標角色 14 /// </summary> 15 public interface IThreeHoleSocket 16 { 17 void Request(); 18 } 19 20 /// <summary> 21 /// 介面卡類提供了三孔插座的外觀,但其本質是兩孔插座 22 /// </summary> 23 public class PowerAdapter : TwoHoleSocket, IThreeHoleSocket 24 { 25 public void Request() 26 { 27 Console.WriteLine("提供三孔插座的外觀"); 28 //執行兩孔插座的功能 29 this.SpecificRequest(); 30 } 31 } 32 33 /// <summary> 34 /// 使用者端 35 /// </summary> 36 class Client 37 { 38 static void Main(string[] args) 39 { 40 //使用者端可以通過介面卡來使用這個兩孔插座了(因為外觀已經是三孔的了) 41 IThreeHoleSocket threeHoleSocket = new PowerAdapter(); 42 threeHoleSocket.Request(); 43 Console.ReadKey(); 44 } 45 }
TwoHoleSocket類代表原有的兩孔插座,IThreeHoleSocket介面來規範三孔插座的外觀。
PowerAdapter類代表介面卡,將兩孔插座賦予三孔插座的外觀。
這樣使用者就可以使用這個介面卡來使用這個三頭插頭的空調了。
從範例中可以看出,類介面卡只要是用繼承來實現的,但如果有很多個類進行適配,這個方式就不支援了。
物件介面卡
1 /// <summary> 2 /// 兩孔插座---被適配者 3 /// </summary> 4 public class TwoHoleSocket 5 { 6 public void SpecificRequest() 7 { 8 Console.WriteLine("兩孔插座"); 9 } 10 } 11 12 /// <summary> 13 /// 三孔插座---目標角色 14 /// </summary> 15 public class ThreeHoleSocket 16 { 17 // 使用者端需要的方法 18 public virtual void Request() 19 { 20 //具體實現 21 } 22 } 23 24 /// <summary> 25 /// 介面卡類提供了三孔插座的外觀,但其本質是兩孔插座 26 /// </summary> 27 public class PowerAdapter : ThreeHoleSocket 28 { 29 //參照兩孔插座的範例,從而將使用者端與TwoHoleSocket聯絡起來 30 public TwoHoleSocket twoHoleSocket = new TwoHoleSocket(); 31 public override void Request() 32 { 33 Console.WriteLine("提供三孔插座的外觀"); 34 this.Request(); 35 //執行兩孔插座的功能 36 twoHoleSocket.SpecificRequest(); 37 } 38 } 39 40 /// <summary> 41 /// 使用者端 42 /// </summary> 43 class Client 44 { 45 static void Main(string[] args) 46 { 47 //使用者端可以通過介面卡來使用這個兩孔插座了(因為外觀已經是三孔的了) 48 ThreeHoleSocket threeHoleSocket = new PowerAdapter(); 49 threeHoleSocket.Request(); 50 Console.ReadKey(); 51 } 52 }
從範例中可以看出,物件介面卡其實就是在介面卡類中建立了一個被適配者的範例,從而將兩者聯絡在一起。
這種方式採用 「物件組合」的方式,更符合鬆耦合。
總而言之,介面卡就是一個第三方類,將不合時宜的東西轉換成符合心意的工具類。
本質就是轉換。