第6章 适配器模式(Adapter Pattern)

本文介绍了适配器模式的概念及应用场景,通过一个日记记录方法的例子,详细解释了如何使用适配器模式解决接口不兼容的问题,并探讨了其优缺点。

原文 第6章 适配器模式(Adapter Pattern)

概述

  将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

 解决的问题

  即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

注:

       在GoF的设计模式中,对适配器模式讲了两种类型,类适配器模式对象适配器模式。由于类适配器模式通过多重继承对一个接口与另一个接口进行匹配,而C#、java等语言都不支持多重继承,因而这里只是介绍对象适配器。

类关系图

举例:

        比如我们目前公司采用一个第三方日记记录的方法,随着版本的更新,第三方已经不提供旧版本的方法,提供了一个新版本的方法,方法名跟类命都不一样了。但是我们又想继续用旧版本的方法,而第三方的源码我们又不能修改,所以我们就可以用一个适配器来解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
     /// <summary>
     /// 旧版本的方法
     /// </summary>
     class  FileWriteLog 
     {
       
         public  void  Write()
         {
             Console.WriteLine( "旧版本写入日记方法" );
         }
     }
     /// <summary>
     /// 新版本
     /// </summary>
     class  NewFileWriteLog
     {
         public  void  NewWrite()
         {
             Console.WriteLine( "新版本的写入日记的方法" );
         }
     }

我们定义一个适配器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
     /// <summary>
     /// 适配器
     /// </summary>
     class  Adapter 
     {
         private  NewFileWriteLog write =  new  NewFileWriteLog();
         //这里调用新的吸入方法
         public  void  Write()
         {
             write.NewWrite();
         }
     }
     
     //client
     class  Program
     {
         static  void  Main( string [] args)
         {
             Adapter adapter =  new  Adapter();
             adapter.Write();
         }
     }

上面的写法特别的简单,主要是让大家能理解里面的核心,适配器是怎么运作的,就像我们的笔记本适配器一样。

当然在正常的接口定义中肯定也不可能这么的简单,起码第三方的提供的接口,要有一定的重写,继承等功能,这样方便我们调用的时候进行一定的封装,以便后续进行一键修改。

 

我们修改下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
     /// <summary>
     /// 旧版本的方法
     /// </summary>
     class   FileWriteLog 
     {
 
         public  virtual  void  Write()
         {
             Console.WriteLine( "旧版本写入日记方法" );
         }
     }
     
         /// <summary>
     /// 新版本
     /// </summary>
     class  NewFileWriteLog
     {
         public  void  NewWrite()
         {
             Console.WriteLine( "新版本的写入日记的方法" );
         }
     }
 
 
     /// <summary>
     /// 适配器
     /// </summary>
     class  Adapter : FileWriteLog
     {
         private  NewFileWriteLog write =  new  NewFileWriteLog();
         //这里调用新的吸入方法
         public  override  void  Write()
         {
             write.NewWrite();
         }
     }
     
     
     class  Program
     {
         static  void  Main( string [] args)
         {
             FileWriteLog adapter =  new  Adapter();
             adapter.Write();
         }
     }

我们可以用简单工厂对对象的实例化进行封装,这样下次在有改动就需要修改工厂里面的实例化对象即可

1
  FileWriteLog adapter =  new  Adapter();

优点

       通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。

     复用了现存的类,解决了现存类和复用环境要求不一致的问题。

     将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。

     一个对象适配器可以把多个不同的适配者类适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。

缺点

     在一些场景下更换适配器的实现过程比较的复杂

适用的场景

      系统需要使用现有的类,而这些类的接口不符合系统的接口。

 

     想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。

     两个类所做的事情相同或相似,但是具有不同接口的时候。

     旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候。

      使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。

.net中的适配器模式

 

      Adapter模式在.NET Framework中的一个最大的应用就是COM Interop。COM Interop就好像是COM和.NET之间的一条纽带,一座桥梁。我们知道,COM组件对象与.NET类对象是完全不同的,但为了使COM客户程序象调用COM组件一样调用.NET对象,使.NET程序像使用.NET对象一样使用COM组件,微软在处理方式上采用了Adapter模式,对COM对象进行包装,这个包装类就是RCW(Runtime Callable Wrapper)。RCW实际上是runtime生成的一个.NET类,它包装了COM组件的方法,并内部实现对COM组件的调用。

        .NET中的另一个Adapter模式的应用就是DataAdapter。ADO.NET为统一的数据访问提供了多个接口和基类,其中最重要的接口之一是IdataAdapter。与之相对应的DataAdpter是一个抽象类,它是ADO.NET与具体数据库操作之间的数据适配器的基类。DataAdpter起到了数据库到DataSet桥接器的作用,使应用程序的数据操作统一到DataSet上,而与具体的数据库类型无关。甚至可以针对特殊的数据源编制自己的DataAdpter,从而使我们的应用程序与这些特殊的数据源相兼容


   设计模式系列文章入口

posted on 2014-05-10 18:24 NET未来之路 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/3720819.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值