適配器模式(Adapter Pattern): 將某個類的介面轉換成客戶端期望的另一個介面表示,主要的目的是相容性,讓原本因介面不匹配不能一起工作的兩個類可以協同工作。如讀卡器是作為記憶體卡和筆記本之間的適配器,需要將記憶體卡插入讀卡器,再將讀卡器插入筆記本,這樣筆記本就可以讀取記憶體卡了。 適配器模式的 ...
適配器模式(Adapter Pattern):
將某個類的介面轉換成客戶端期望的另一個介面表示,主要的目的是相容性,讓原本因介面不匹配不能一起工作的兩個類可以協同工作。如讀卡器是作為記憶體卡和筆記本之間的適配器,需要將記憶體卡插入讀卡器,再將讀卡器插入筆記本,這樣筆記本就可以讀取記憶體卡了。
適配器模式的主要角色:
1、目標介面(Target):當前系統業務所期待的介面,它可以是抽象類或介面。
2、適配者類(Adaptee):被訪問和適配的現存組件庫中的組件介面。
3、適配器類(Adapter):轉換器,通過繼承或引用適配者的對象,把適配者介面轉換成目標介面,讓客戶按目標介面的格式訪問適配者。
適配器模式主要分三類:類適配器模式、對象適配器模式、介面適配器模式(java中使用)。接下來我們來詳細介紹下這三種形式。
1、類適配器模式
當前去外地出差,工作繁忙,回到賓館也不得不工作。當你拿出電腦,準備接電源,卧槽...不支持!!!電源是兩孔的,而插座是三孔的,怎麼辦呢?你會想到去樓下小商店買個轉換插座,將三孔插座轉成兩孔的來用,簡直太聰明瞭。
(以該圖代替,原理類似)
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 Computer computer = new Computer(new TwoHoleSocket()); 6 computer.Connect(); 7 // 類適配器的缺點 8 TwoHoleSocket twoHoleSocket = new TwoHoleSocket(); 9 twoHoleSocket.Test(); 10 } 11 } 12 13 internal class Computer 14 { 15 private readonly Transformer transformer; 16 17 public Computer(Transformer transformer) 18 { 19 this.transformer = transformer; 20 } 21 22 public void Connect() 23 { 24 transformer.Transfrom(); 25 Console.WriteLine("連接成功!!!"); 26 } 27 } 28 29 /// <summary> 30 /// 三孔插座Adaptee 31 /// </summary> 32 internal class ThreeHoleSocket 33 { 34 public void Show() 35 { 36 Console.WriteLine("我是三孔插座"); 37 } 38 39 public void Test() 40 { 41 Console.WriteLine("我是多餘的"); 42 } 43 } 44 45 /// <summary> 46 /// 轉換器Target 47 /// </summary> 48 internal interface Transformer 49 { 50 void Transfrom(); 51 } 52 53 /// <summary> 54 /// 兩孔插座Adapter 55 /// </summary> 56 internal class TwoHoleSocket : ThreeHoleSocket, Transformer 57 { 58 public void Transfrom() 59 { 60 base.Show(); 61 Console.WriteLine("轉換中。。。。"); 62 Console.WriteLine("哈哈哈,我已經是兩孔插座"); 63 } 64 }view code
分析:對於類適配器來說,Adapter與Adaptee過於耦合,增加了使用成本,且會暴露不必要的方法。
2、對象適配器模式
當手機沒電需要充電,你不可能直接使用220V的電壓,如果你真這麼做了,請註意人身安全及購買一臺新機。此時,充電器就起到了轉換器的作用,將220V電壓轉換成手機可使用的5V電壓。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Phone phone = new Phone(); 6 phone.charging(new VoltageAdapter(new Voltage220V())); 7 } 8 } 9 10 class Phone 11 { 12 public void charging(Voltage5V voltage5V) 13 { 14 voltage5V.output5V(); 15 } 16 } 17 18 class Voltage220V 19 { 20 public void output220V() 21 { 22 Console.WriteLine("220V"); 23 } 24 } 25 26 interface Voltage5V 27 { 28 void output5V(); 29 } 30 31 class VoltageAdapter : Voltage5V 32 { 33 private readonly Voltage220V voltage220V; 34 35 public VoltageAdapter(Voltage220V voltage220V) 36 { 37 this.voltage220V = voltage220V; 38 } 39 40 public void output5V() 41 { 42 voltage220V.output220V(); 43 Console.WriteLine("5V"); 44 } 45 }view code
分析:以松耦合的方式實現適配器模式,推薦使用。
3、介面適配器模式(java中使用,c#中能夠實現但意義不大)
1 class Program 2 { 3 static void Main(string[] agrs) 4 { 5 Power5VAdapter power5VAdapter = new Power5VAdapter(new AC220()); 6 Console.WriteLine(power5VAdapter.output5V()); 7 } 8 } 9 10 class AC220 11 { 12 public int output220V() 13 { 14 int output = 220; 15 return output; 16 } 17 } 18 19 interface Voltage 20 { 21 int output5V(); 22 int output9V(); 23 int output12V(); 24 int output24V(); 25 } 26 27 abstract class PowerAdapter : Voltage 28 { 29 private readonly AC220 ac220; 30 31 public PowerAdapter(AC220 ac220) 32 { 33 this.ac220 = ac220; 34 } 35 36 public virtual int output12V() 37 { 38 return ac220.output220V(); 39 } 40 41 public virtual int output24V() 42 { 43 return ac220.output220V(); 44 } 45 46 public virtual int output5V() 47 { 48 return ac220.output220V(); 49 } 50 51 public virtual int output9V() 52 { 53 return ac220.output220V(); 54 } 55 } 56 57 class Power5VAdapter : PowerAdapter 58 { 59 private AC220 ac220; 60 61 public Power5VAdapter(AC220 ac220) 62 : base(ac220) 63 { 64 this.ac220 = ac220; 65 } 66 67 public override int output5V() 68 { 69 int output = 0; 70 if (this.ac220 != null) 71 { 72 output = this.ac220.output220V() / 44; 73 } 74 return output; 75 } 76 }view code
優點:
1、客戶端通過適配器可以透明地調用目標介面。
2、復用了現存的類,開發人員不需要修改原有代碼而重用現有的適配者類。
3、將目標類和適配者類解耦,解決了目標類和適配者類介面不一致的問題。
缺點:
1、對類適配器來說,更換適配器的實現過程比較複雜。
2、過多的適配器,會讓系統零亂,不易整體進行把握。