適配器模式簡述: 定義:將一個類的介面轉化成客戶希望的另一個介面,適配器模式讓那些介面不相容的類可以一起工作。別名(包裝器[Wrapper]模式) 它屬於創建型模式的成員,何為創建型模式:就是關註如何將現有類或對象組織在一起形成更大的結構。由於系統中存在類和對象,所以存在兩種結構型模式:類結構型模式 ...
- 適配器模式概述
定義:將一個類的介面轉化成客戶希望的另一個介面,適配器模式讓那些介面不相容的類可以一起工作。別名(包裝器[Wrapper]模式)
它屬於創建型模式的成員,何為創建型模式:就是關註如何將現有類或對象組織在一起形成更大的結構。由於系統中存在類和對象,所以存在兩種結構型模式:類結構型模式(關註類的組合,由多個類組成一個更大的系統,一般只有繼承關係和實現關係)、對象結構型模式(關註類和對象的組合,通過關聯關係,在一個類中定義另一個類的對象,然後通過該對象調用相關方法)。
適配器,適配器,筆記本要用的就是電源適配器(AC Adapter),沒錯,有了電源適配器,我們筆記本就能使用本來不能使用的220V的電壓了,這也就是電源適配器的功勞。我們這裡也一樣,引入適配器模式以相容某些結構。
- 適配器模式的結構
結構:
- Target(目標抽象類):它定義客戶所需的介面(能用的電壓),可以是abstract類或介面,也可以是具體類。在類適配器中,只能是介面(單繼承)
- Adapter(適配器類):可調用另一個介面,作為轉化器。,對Adaptee和Target進行適配,相當於電源適配器。類適配中實現Target介面並繼承Adaptee來實現產生關係,在對象適配器中,繼承Targer並關聯Adaptee對象產生聯繫(如上圖)
- Adaptee(適配者類):它是被適配的,定義一個已存在的介面,相當於220V電壓。一般是一個具體類(有了才能去適配)。
簡單分析:
上圖是課上老師給的例子,這樣理解起來就很容易了。偽裝者即適配器類,由於要用到鴨子的方法,所以用火雞偽裝下,它關聯鴨子,就可以在內部生成鴨子的對象。即披著鴨子皮的火雞,讓小朋友們誤以為是鴨子在表演。
- 預設適配器模式(Default Adapter Pattern)
定義:缺當不需要實現一個介面所提供的所有方法時,可先設計一個抽象類實現該介面,併為介面中每個方法提供一個預設實現(空方法),那麼該抽象類的子類可以選擇性地覆蓋父類的某些方法來實現需求,它適用於不想使用一個介面中的所有方法的情況,又稱為單介面適配器模式。
結構:
- ServiceInterface(適配者介面):在該介面中聲明許多方法
- AbstractServiceClass(預設適配器類):核心類,使用空方法實現ServiceInteface中的方法,對它實例化無意義
- ConcrServiceClass(具體業務類):預設適配器類的子類,直接繼承適配器類,根據需要有選擇性的實現上述中的某個方法
- 雙向適配器
適配器中同時包含對目標類和適配器類的引用,適配者可以通過調用目標類中的方法,目標類也可以通過它調用適配者類中的方法,該適配器即雙向適配器
結構:
1 public class Adapter : Target, Adaptee 2 { 3 //同時維持對抽象目標類和適配者的引用 4 private Target target; 5 private Adaptee adaptee; 6 7 public Adapter(Target target) 8 { 9 this.target = target; 10 } 11 12 public Adapter(Adaptee adaptee) 13 { 14 this.adaptee = adaptee; 15 } 16 17 public void Request() 18 { 19 adaptee.SpecificRequest(); 20 } 21 22 public void SpecificRequest() 23 { 24 target.Request(); 25 } 26 }
應用:實現一個雙向適配器實例,使得貓(Cat)可以學狗(Dog)叫(Cry()),狗可以學貓捉老鼠(CatchMouse())
實現:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 適配器模式 7 { 8 public interface IDog 9 { 10 void Action(); 11 void Wang(); 12 } 13 14 public interface ICat 15 { 16 void Cry(); 17 void CatchMouse(); 18 } 19 20 public class Snoopy : IDog 21 { 22 public void Action() 23 { 24 } 25 26 public void Wang() 27 { 28 Console.WriteLine("汪汪的叫......."); 29 } 30 } 31 32 public class Tom : ICat 33 { 34 public void Cry() 35 { 36 } 37 38 public void CatchMouse() 39 { 40 Console.WriteLine("捉老鼠....."); 41 } 42 } 43 44 public class Adapter : ICat, IDog 45 { 46 private IDog dog; 47 private ICat cat; 48 49 public Adapter(IDog d) 50 { 51 this.dog = d; 52 } 53 54 public Adapter(ICat c) 55 { 56 this.cat = c; 57 } 58 59 public void Cry() 60 { 61 dog.Wang(); 62 } 63 64 public void CatchMouse() 65 { 66 cat.CatchMouse(); 67 } 68 69 public void Action() 70 { 71 cat.CatchMouse(); 72 } 73 74 public void Wang() 75 { 76 dog.Wang(); 77 } 78 } 79 80 class Program 81 { 82 static void Main(string[] args) 83 { 84 //這裡貓想學狗叫,實現Cry的方法,所以適配者首先是一隻貓,它要實現貓的Cry的方法, 85 //但適配者是假的,它只能藉助狗的方法來實現。 86 ICat cat = new Adapter(new Snoopy()); 87 Console.Write("Cat learn:"); 88 cat.Cry(); 89 Console.Read(); 90 } 91 } 92 93 }View Code
- 適配器模式的優點
- 將目標類和適配者類解耦,通過引入一個適配器類來重用現有的適配者類,無須修改原有結構
- 增加了類的透明性和復用性,提高了適配者的復用性,同一個適配者類可以在多個不同的系統中復用
- 靈活性和擴展性非常好
- 類適配器模式:置換一些適配者的方法很方便
- 對象適配器模式:可以把多個不同的適配者適配到同一個目標,還可以適配一個適配者的子類
- 適配器模式的缺點
- 類適配器模式
- 一次最多只能適配一個適配者類,不能同時適配多個適配者
- 適配者類不能為最終類
- 目標抽象類只能為介面,不能為類
- 對象適配器模式
- 對象適配器模式:在適配器中置換適配者類的某些方法比較麻煩
- 適配器模式的適用環境
- 系統需要使用一些現有的類,而這些類的介面不符合系統的需要,甚至沒有這些類的源代碼
- 創建一個可以重覆使用的類,用於和一些彼此之間沒有太大關聯的類,包括一些可能在將來引進的類一起工作