设计模式之ADAPTER

设计模式之ADAPTER_6分词条

目录 [隐藏]

设计模式之ADAPTER 日常生活中的适配器

 

   适配器的例子在日常生活中随处可见。 例如:中国的电源电压为 220V ,而日本的电源电压 110V ,在国内使用日本原装电器时,就必须有一个电源适配器将 220V 的电压适配至 110V 。

     新的电脑鼠标一般都是 USB 接口,而旧的电脑机箱上根本就没有 USB 接口,而只有一个 PS2 接口,这时就必须有一个 PS2 转 USB 的适配器,将 PS2 接口适配为 USB 接口。

     一般家庭中电源插座有的是两个孔(两项式)的,也有三个孔(三项式)的。很多时候我们可能更多地使用三个引脚的插头,但是那种两孔的插座就不能满足我们的需求,此时我们一般会买一个拖线板,该拖线板的插头是是两脚插头,这样就可以插入原先的两孔插座,同时拖线板上带有很多两孔、三孔的插座!这样不仅可以扩容,更主要的是将两孔的插座转变为三孔的插座。

    图1为一个将220v 电源转换为5v 电源的适配器,图2为将PS2 接头转换为 USB 接头的适配器,,图3二孔插座适配为三孔插座的插座适配器。

设计模式之ADAPTER设计模式之ADAPTER

图 1 电源适配器       图 2 鼠标适配器

设计模式之ADAPTER设计模式之ADAPTER

图 3 插座适配器

设计模式之ADAPTER 软件工程中的应用

 

     如果你有一个存在的系统需要插入一个新的类库,但是新的类库并不能匹配你写的系统,如下图:

设计模式之ADAPTER

      现在你不想更改存在的旧系统,新的类库也不能修改,这时候我们就需要写一个适配器了,用这个适配器来适配新类库的接口。如下图:

设计模式之ADAPTER设计模式之ADAPTER

    用了适配器之后的整个系统,如下图:

设计模式之ADAPTER设计模式之ADAPTER

设计模式之ADAPTER 如何使用

 

     实现Adapter方式,有两种方式:组合(composition)和继承(inheritance).

     假设我们要打桩,有两种类:方形桩,圆形桩.
public class SquarePeg{
  public void insertSquare(String str){
    System.out.println("SquarePeg insertSquare():" +str);
  }

}

public class RoundPeg{
  public void insertRound(String msg){
    System.out.println("RoundPeg insertRound():" +msg);
      }
}

     现在有一个应用 ,需要圆桩能当方桩来打.那么我们需要将这两个没有关系的类综合应用.假设RoundPeg我们没有源代码,或源代码我们不想修改,那么我们使用Adapter来实现这个应用:

public class PegAdapter extends SquarePeg {

private RoundPeg roundPeg;

public PegAdapter(RoundPeg peg) {
         this.roundPeg = peg;
}

public void insertSquare(String str) {
         roundPeg.insertRound(str);
         }
}

     在上面代码中 ,RoundPeg属于Adaptee,是被适配者.PegAdapter是Adapter,将Adaptee(被适配者RoundPeg)和Target(目标SquarePeg)进行适配.实际上这是将组合方法(composition)和继承(inheritance)方法综合运用.

     PegAdapter首先继承SquarePeg,然后使用new的组合生成对象方式,生成RoundPeg的对象roundPeg,再重载父类insertSquare()方法。从这里,你也了解使用new生成对象和使用extends继承生成对象的不同,前者无需对原来的类修改,甚至无需要知道其内部结构和源代码.

     如果你有些 Java使用的经验,已经发现,这种模式经常使用。

设计模式之ADAPTER 定义

 

      转换一个类的接口为客户端所需要的接口,将两个不兼容的纠合在一起使用,这个转换的类就是适配器类。它属于结构型模式,需要有Adaptee(被适配者)和Adaptor(适配器)两个身份.它的宗旨就是,保留现有类所提供的服务,向客户提供接口,以满足客户的期望。

设计模式之ADAPTER 结构

 

Adapter模式有两种结构,分别是类的适配与对象的适配。

1、类的适配

设计模式之ADAPTER设计模式之ADAPTER

角色分析:

     Target目标角色:这是一个接口,定义了客户所期望的操作 Adaptee源角色:这是我们原有的产品,也是需要被适配的产品。

     Adapter适配器角色:在Target目标角色与Adaptee源角色之间提供一种过渡,即把Adaptee源角色所提供的接口转换为Target目标角色所提供的接口。 从结构图中可以很容易的知道,适配器角色Adapter必须要继承Targe目标角色(一个接口)与源角色Adaptee。

源码:

public class Adaptee{

  public void specialRequest(){

     System.out.println("Called SpecificRequest() in Adaptee ");

      }

}

public interface Target{

   public void request();

}

public class Adapter extends Adaptee implements Target{

    public void request(){

        this.specialRequest();

     }

}

2、对象的适配

设计模式之ADAPTER设计模式之ADAPTER

        两种结构的角色其实都是一样的,客户的调用流程也是相同的。不同之处于两者在包装Adaptee源角色时,前者(类适配)包装的是Adaptee类(因为它同时从Target与Adaptee继承而来,可想而知,类适配的Adatper必须是一个具体类,而Target只能是一个接口),后者(对象适配)则直接包装了一个源Adaptee的实例。这一点如果放在代码中,则更容易体现出来。此处的差别导致了在具体实现时各个角色的不同实现方式(以类还是以接口)。

      让我们来看一下前面讲的生活中的适配器例子的插座对象适配图:

设计模式之ADAPTER设计模式之ADAPTER

源码: Adaptee和Target类同上。

public class Adapter implements Target{

    Adaptee adaptee = new Adaptee();

    public void request(){

           adaptee.specialRequest();

    }

}

3,类适配和对象适配的不同

设计模式之ADAPTER设计模式之ADAPTER

设计模式之ADAPTER 为何使用

 

      我们经常碰到要将两个没有关系的类组合在一起使用,第一解决方案是:修改各自类的接口,但是如果我们没有源代码,或者,我们不愿意为了一个应用而修改各自的接口。 怎么办? 使用 Adapter,在这两种接口之间创建一个混合接口(混血儿).

1、 系统需要使用现有的类,而此类的接口不符合系统的需要。
2、 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起 工作。这些源类不一定有很复杂的接口。
3、 (对对象适配器而言)在设计里,需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际.

设计模式之ADAPTER 几个要点

 

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

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

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

设计模式之ADAPTER 进一步使用

 

    上面的PegAdapter是继承了SquarePeg,如果我们需要两边继承,即继承SquarePeg 又继承RoundPeg,因为Java中不允许多继承,但是我们可以实现(implements)两个接口(interface)

public interface IRoundPeg{
  public void insertRound(String msg);
}

public interface ISquarePeg{
  public void insertSquare(String str);

}

下面是新的 RoundPeg 和SquarePeg, 除了实现接口这一区别,和上面的没什么区别。
public class SquarePeg implements ISquarePeg{
  public void insertSquare(String str){
    System.out.println("SquarePeg insertSquare():"+ str);
  }

}

public class RoundPeg implements IRoundPeg{
  public void insertRound(String msg){
    System.out.println("RoundPeg insertRound():"+msg);
  }
}

下面是新的 PegAdapter,叫做two-way adapter:

public class PegAdapter implements IRoundPeg,ISquarePeg{
private RoundPeg roundPeg;

private SquarePeg squarePeg;

// 构造方法
public PegAdapter(RoundPeg peg) {
     this.roundPeg = peg;
}

// 构造方法
public PegAdapter(SquarePeg peg) {
     this.squarePeg = peg;
}

public void insertSquare(String str) {
     roundPeg.insertRound(str);
}

public void insertRound(String msg) {
    squarePeg.insertSquare(msg);
}

}

     还有一种叫 Pluggable Adapters,可以动态的获取几个adapters中一个。使用Reflection技术,可以动态的发现类中的Public方法。

设计模式之ADAPTER 现实中的应用

 

     在JDK1.0和1.1版本里没有Java聚集(Collectcion)的框架,这一框架是在JDK1.2版本中给出的。与引起相对应,JDK1.0和1.1版本里提供了Enumeration接口,而JDK1.2版本给出了Iterator接口。如果有很多的Java代码是为老版本Java编译器写的,使用的是Enumeration,现在想使用新版本编译器和新的Java聚集库包的话,需要将已有代码的Iterator接口转换成Enumeration接口。因为Java聚集要求的Iterator接口,只有这样才能使已有的代码可以使用新版本的聚集对象。反之,需要将旧代码的Enumeration接口转换成Iterator接口。

Enumeration接口类图:

<<interface>>

Enumeration

hasMoreElements ()

nextElement ()

Iterator接口类图:

<<interface>>

Iterator

hasNext ()

next ()

remove ()

适配Enumeration成为Iterator:

设计模式之ADAPTER设计模式之ADAPTER

适配Enumeration成为Iterator的源代码:

public class EnumerationIterator implements Iterator
{
  Enumeration enum;
  public EnumerationIterator(Enumeration enum){
     this.enum=enum;
  }
  public boolean hasNext(){
     return enum.hasMoreElements();
  }
  public Object next(){
     return enum.nextElement();
  }
  public void remove(){
     throw new UnsupportedOperationException();
  }
}

设计模式之ADAPTER 在架构层次上的应用

 

   1,JDBC驱动软件与适配器模式     

     Sun Microsystem在1996年公开了Java语言的数据库连接工具JDBC。JDBC使得Java语言程序能够连接数据库上,并使用SQL(Strucured Query Language)来查询和修改数据和数据定义。

     JDBC给出一个客户端通用的界面。每个数据库引擎的JDBC驱动软件都是一个介于JDBC接口和数据库引擎接口之间的适配器软件,如下图所示。

设计模式之ADAPTER设计模式之ADAPTER

       抽象的JDBC接口和各个数据库引擎的API之间都需要相应的适配器软件,即为各个数据库引擎准备的驱动软件。

  2,JDBC/ODBC桥梁

      JDBC的想法与微软的ODBC想法很接近。只要有合适的驱动软件,JDBC就可以直接连接到数据库上。如果没有合适的JDBC驱动软件,用户也可以通过ODBC驱动软件把JDBC通过一个JDBC/ODBC桥梁软件与ODBC驱动软件连接起来,从而达到连接数据库的目的。ODBC/JDBC桥梁的架构图如下图所示。

设计模式之ADAPTER设计模式之ADAPTER

      JDBC库不可能和ODBC的库有相同的接口,因此,使用适配器模式将ODBC的API接口改为JDBC的接口就是唯一可行的方法。因此,JDBC/ODBC桥梁是适配器模式的具体应用。

附图

上传图片 

互动百科的词条(含所附图片)系由网友上传,如果涉嫌侵权,请与客服联系,我们将按照法律之相关规定及时进行处理。如需转载,请注明来源于www.hudong.com

被引用: 本词条已被如下媒体引用 我来补充
开放分类: 我来补充

讨论区

更多>>

编辑者

共2人协作

相关词条

羽泉
重构
PB
Enterprise JavaBean
sybase
JDBC
java数据库连接
ODBC
DAO
Data Access Objects
更多

Copyright © 2005-2009 hudong.com Ltd. All Rights Reserved. 互动在线 版权所有