從接觸領域驅動設計的初學階段,到實現一個舊系統改造到DDD模型,再到按DDD規範落地的3個的項目。對於領域驅動模型設計研發,從開始的各種疑惑到吸收各種先進的理念,目前在技術實施這一塊已經基本比較成熟。在既往經驗中總結了一些在開發中遇到的技術問題和解決方案進行分享。 ...
基礎介紹:
想象這樣一個場景,原項目中介面返回的數據是XML格式的數據,但現在來了一個新客戶,它期望介面返回的數據類型為json格式的。
想要實現要麼就是改原有介面,但這樣就違反了開閉原則,容易出現未知bug,影響到老客戶的正常使用。
而如果寫一個適配器類也就是轉換類(第三方類),將原本返回的XML格式數據轉換成json格式數據,而具體數據是怎麼來的則直接用原有介面方法就可以。
新客戶只需要調用適配器類就可以了,而老客戶這邊也不會進行任何修改處理。
如果再有新的客戶要求其他類型的返回,只需要在適配器類中增加相應的轉換處理就可以了。
再思考一個問題,現實生活中空調插頭一般都是三頭的,但如果家裡只有兩孔插座,那必然是插不進去的。
以前老的辦法那就是把三頭插座掰掉一個,另外兩個也掰直,這樣做存在很大的安全隱患,而且有時並不能工作。
而如果提供一個擁有三孔插座和兩頭插頭的轉換器的話,那空調可以先插在這個轉換器上,然後這個轉換器再插在插座上就可以了。
本質並沒有變,只是將二孔插座包裝了一下,向外界提供了一個三孔插座的外觀以供客戶使用。
適配的本質就是轉換,將不滿足使用條件的東西通過第三方類進行加工處理成可使用的東西。
適配器模式(Apapter Pattern)是一種結構型設計模式,將一個類的介面轉換成客戶希望的另一個介面。適配器模式使得原本由於介面相容而不能一起工作的那些類可以一起工作。
適配器模式用來解決現有對象與客戶端期待介面不一致的問題。
- 目標角色(Target):描述了其他類與客戶端代碼合作時必須遵循的協議。
- 客戶角色(Client):與符合Target介面的對象協同。
- 被適配(服務類,功能類)(Adaptee):定義一個已經存在並已經使用的介面,這個介面需要適配。 客戶端與其介面不相容, 因此無法直接調用其功能。
- 適配器(Adapter) :適配器模式的核心。適配器接受客戶端通過適配器介面發起的調用,同時根據其內在邏輯調用對應服務類。客戶端代碼只需通過介面與適配器交互即可, 無需與具體的服務類耦合。
優缺點:
- 單一職責原則:可以將介面或數據轉換代碼從主要業務邏輯中分離。
- 開閉原則: 客戶端介面只需適配器進行交互, 能在不修改現有代碼的情況下在程式中添加新類型的適配器。
- 通過適配器模式,可以使兩個不相容的介面協同工作,避免了修改現有代碼的需要。
- 提高了代碼的復用性和靈活性,因為適配器可以重覆使用,並且可以在不同的場景中使用。
- 降低了系統的耦合度,適配器模式允許系統中的各個組件相互獨立地演化。
- 代碼整體複雜度增加 :因為需要新增一系列介面和類。 有時直接更改服務類使其與其他代碼相容會更簡單。
應用場景:
系統需要復用現有類,但是介面又與復用環境要求不一致的情況。
- 舊系統與新系統的相容:可以使新系統能夠無縫地與老舊系統進行通信。
- 第三方組件的集成:適配器可以將第三方組件的介面轉換為符合我們系統需求的介面形式,從而能夠順利地集成到我們的系統中。
- 多個類庫之間的互操作:適配器模式可以起到橋梁的作用。
創建方式:
適配器模式有兩種實現結構,對象適配器和類適配器。
試想一下,目前有一個三頭插頭的空調,需要一個三孔插座,但目前只有一個兩孔插座。
編寫一個適配器來包裝一下這個兩孔插座,讓用戶可以使用這個空調。
-
類適配器
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 }
View CodeTwoHoleSocket類代表原有的兩孔插座,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 }
View Code從實例中可以看出,對象適配器其實就是在適配器類中創建了一個被適配者的實例,從而將兩者聯繫在一起。
這種方式採用 “對象組合”的方式,更符合松耦合。
總結:
總而言之,適配器就是一個第三方類,將不合時宜的東西轉換成符合心意的工具類。
本質就是轉換。
作者:少年真愛 出處:https://www.cnblogs.com/mingnianjiehunba/p/17729599.html 博主的文章沒有高度、深度和廣度,只是湊字數。由於博主的水平不高,不足和錯誤之處在所難免,希望大家能夠批評指出。 博主是利用讀書、參考、引用、抄襲、複製和粘貼等多種方式打造成自己的文章,請原諒博主成為一個無恥的文檔搬運工!