适配器模式(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、过多的适配器,会让系统零乱,不易整体进行把握。

02-13 15:25