Adapter 适配器模式(设计模式03)

疑问:

  • 在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。 如何应对这种“迁移的变化”?
  • 如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?

定义:

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

一、对象适配器

对象适配器采用对象组合,通过引用一个类与另一个类接口 在对象适配器中通过组合获得Adaptee对象 通过调用Adaptee对象的方法,转换后返回Target结果。

二、类适配器

类适配器通过多继承对一个接口与另一个接口进行匹配。
Target定义了Client使用的与特定领域相关的接口,Client通过调用Target实现某一个特定的操作。Adaptee是一个已经存在的类,需要与Target协同工作,这个接口需要适配。Adapter适配器适配Adaptee和Target接口。在类适配器中,通过继承获得Adaptee中的方法。

.NET不支持多重继承,因此当Target是一个类,而不是一个接口时无法实现类适配器,这时需要使用对象适配器。

三、生活中的例子

在国内使用的电源供电电压为220V,美国为380V,当你出差到美国,你的电器需要220V的电压,但旅馆里不提供220V,只提供380,所以,你到市场买了一个电源适配器,在接上适配器后,旅馆里的电源就可以使用在你的电器上了。

Target:标准电源
Adaptee:美国电源
Adapter:适配器

1、实现-Target

 /// <summary>
    /// 目标:Target
    /// </summary>
    public class StandardPower
    {
        /// <summary>
        /// 供电
        /// </summary>
        /// <returns></returns>
        public virtual int SupplyPower()
        {
            Console.Write("正常SupplyPower,电压:");
            return 220;
        }
    }

2、实现-Adaptee

 /// <summary>
    /// 要适配的对象:Adaptee
    /// </summary>
    public class AmericanPower
    {
        public int SupplyPower()
        {
            Console.Write("在美国供给380V电压");
            return 380;
        }
    }

3、实现-Adapter

 /// <summary>
    /// 适配器:Adapter
    /// </summary>
    public class PowerAdapter : StandardPower
    {
        /// <summary>
        /// 当地电源
        /// </summary>
        private AmericanPower localPower = new AmericanPower();
        public override int SupplyPower()
        {
            int v = localPower.SupplyPower();
            if (v != 220)
            {
                //这里做一些转换工作
                v = 220;
            }
            Console.WriteLine("转换后的电压:{0}", v.ToString());
            return v;//转换后,即适配后
        }
    }

4、实现-使用

 StandardPower power = null;

            //在中国的时候
            power = new StandardPower();
            Console.WriteLine(power.SupplyPower());

            //到美国以后,买一个适配器
            power = new PowerAdapter();
            Console.WriteLine("适配后提SupplyPower源电压为:{0}", power.SupplyPower());

            //让控制台 等待
            Console.ReadLine();

四、.NET中的Adapter模式

1.适配器模式在.NET Framework中的一个最大的应用就是COM Interop。

COM Interop就好像是COM和.NET之间的一座桥梁(关于COM互操作更多内容可以参考我的互操作系列)。COM组件对象与.NET类对象是完全不同的,但为了使.NET程序
象使用.NET对象一样使用COM组件,微软在处理方式上采用了Adapter模式,对COM对象进行包装,这个包装类就是RCW(Runtime Callable Wrapper)。RCW实际上是runtime生成的一个.NET类,它包装了COM组件的方法,并内部实现对COM组件的调用。如下图所示:

2..NET中的另外一个适配器模式的应用就是DataAdapter。

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

五、实现要点

适配器模式重在转换接口,它能够使原本不能在一起工作的两个类一起工作,所以经常用在类库复用,代码迁移等方面,有一种亡羊补牢的味道

类适配器和对象适配器可以根据具体实际情况来选用,但一般情况建议使用对象适配器模式

六、效果

通过类的继承或者对象的组合转换已有的接口为目标接口

七、适用性

需要使用一个已经存在的类,但接口与设计要求不符。

希望创建一个可以复用的类,该类可以与其他不相关的类或者是将来不可预见的类协同工作。

八、总结

Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况” ,在遗留代码复用、类库迁移等方面非常有用。

GoF 23 定义了两种Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。

Adapter模式可以实现的非常灵活,不必拘泥于Gof23中定义的两种结构。例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。

Adapter模式本身要求我们尽可能地使用“面向接口的编程”风格,这样才能在后期很方便地适配。

作者:jiankunking 出处:http://blog.csdn.net/jiankunking

源码下载:http://download.csdn.net/detail/xunzaosiyecao/9543274
小注:
本文部分资料整理自网络,在此表示感谢。
1、 C#设计模式(7)——适配器模式(Adapter Pattern)

2、本杰.NET 张波的PPT资料

时间: 2024-10-22 06:27:41

Adapter 适配器模式(设计模式03)的相关文章

Adapter适配器模式在JavaScript设计模式编程中的运用分析_基础知识

定义适配器模式(Adapter)是将一个类(对象)的接口(方法或属性)转化成客户希望的另外一个接口(方法或属性),适配器模式使得原本由于接口不兼容而不能一起工作的那些类(对象)可以一些工作.速成包装器(wrapper). 适配器的别名是包装器(wrapper),这是一个相对简单的模式.在程序开发中有许多这样的场景:当我们试图调用模块或者对象的某个接口时,却发现这个接口的格式并不符合目前的需求.这时候有两种解决办法,第一种是修改原来的接口实现,但如果原来的模块很复杂,或者我们拿到的模块是一段别人编

php设计模式 建造者模式 与Adapter(适配器模式)

php教程设计模式 建造者模式 与Adapter(适配器模式) 适配器模式 * * 将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作 建造者模式 * * 将一个复杂对象的构建与它的表示分离,使用同样的构建过程可以创建不同的表示 <?php /** * 适配器模式 * * 将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作 */ // 这个是原有的类型 class OldCache { public

Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比_java

Java 适配器模式            最近学习java 基础知识,学习适配器的时候疑惑很多,上网查下资料,对于 Adapter的资料很多,但是比较下本篇不错,这里记录下,大家需要的可以看下. 适配器模式就是把一个类的接口转换成客户端所期待的另外一种接口,从而使原接口不匹配而无法在一起工作的的两个类能在一起工作.从功能上说,这些接口不兼容的类一般具有相同或相似的功能.通常我们通过修改该类的接口来解决这种接口不兼容的情形,但是如果我们不愿意为了一个应用而修改各原接口,或者我们压根儿就没有对象的

设计模式学习笔记(二)—-Adapter适配器模式

GOF<设计模式>一书对Adapter模式是这样描述的: 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使原本由于接口不兼容而不能一起工作的类可以一起工作. 这段话大致是说:我们需要一种方式,为一个功能正确但接口不合的对象创建一个新接口.例如,客户给我们如下需求: 1)为都有"显示"(display)行为的点.线.正方形分别创建类. 2)客户对象不必知道自己到底拥有点.线.还是正方形.它只需知道拥有这些形状中的一个. 也就是说,我们要用一个更高层次的概念将这

php设计模式 Adapter(适配器模式)

复制代码 代码如下: <?php /** * 适配器模式 * * 将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作 */ // 这个是原有的类型 class OldCache { public function __construct() { echo "OldCache construct<br/>"; } public function store($key,$value) { echo "OldCach

php设计模式 Adapter(适配器模式)_php技巧

复制代码 代码如下: <?php /** * 适配器模式 * * 将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作 */ // 这个是原有的类型 class OldCache { public function __construct() { echo "OldCache construct<br/>"; } public function store($key,$value) { echo "OldCach

设计模式学习笔记系列

设计模式学习笔记(二十二)-FlyWeight享元模式 设计模式学习笔记(二十一)-Composite模式 设计模式学习笔记(二十)-Visitor访问者模式 设计模式学习笔记(十九)-Chain of Responsibility职责链模式 设计模式学习笔记(十八)-Mediator中介者模式 设计模式学习笔记(十七)-Memento备忘录模式 设计模式学习笔记(十六)-Proxy模式 设计模式学习笔记(十五)-State模式 设计模式学习笔记(十四)-Command模式 设计模式学习笔记(十

解读设计模式----适配器模式(Adapter Pattern)

在金庸笔下,三大神功都是难得之宝,多少人为得到他而......,仔细的分析下这三大神功,还是北冥较好,呵呵.我们从软件设计的角度来看,这不知算不算得上是一种复用(功力复用)的思想,只不过有点残忍罢.而在软件设计领域里,"复用"在某些时候也会出现很多问题,比如平台不兼容,开发语言不同或是接口不同等多种原因,弄得不好会不会出现既浪费了别人的现有资源,而自己的系统又无法完成呢?这有点像吸星----损人又损己. 企图将设计做好,就能够一劳永逸地坐享其成,这样的愿望就好上面所提到的吸星神功一般,

.NET设计模式-适配器模式(Adapter Pattern)

适配器模式(Adapter Pattern) --.NET设计模式系列之八 Terrylee,2006年2月 概述 在软件系统中,由于应用环境的变化,常常需要将"一些现存的对象"放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的.那么如何应对这种"迁移的变化"?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?这就是本文要说的Adapter 模式. 意图 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口