您的位置:首页 > 编程语言 > Java开发

适配器模式

2016-05-02 22:43 232 查看
Java设计模式----适配器模式

 定义:

属于结构型模式,其主要作用是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
比如你在美国买了台电脑,他是二孔插头,但是国内没有二孔插座,只有三孔的,这时就需要买个适配器了

 
意图宗旨:
保留现有类所提供的服务,向客户提供接口,以满足客户的期望
我们什么时候可以使用它:
1你想使用一个已经存在的类,而它的接口不符合你的需求。你没有二孔插座。
2你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
3你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口——仅适用于对象Adapter。

适配器应用类型举例:

 例如:  DataAdapter,它就是用作DataSet和数据源之间的适配器。DataAdapter通过映射Fill和Update来提供这一适配器。

模式中的角色:
1  Target (目标接口)
   客户所期待的接口。目标可以是具体的或抽象的类。也可以是接口。
2 Adaptee(需要适配的类)
   需要适配的类或适配者类。
3 Adapter(适配器 )
   通过包装一个需要适配的对象,把原接口转换成目标接口。
 
 类图:



例子:



 
代码实现:
 

对象适配器:
package com.yc.Adapter;
 

//接口,被实现时只能实现里面的子方法
//目标接口,或称为标准接口 
public interface Target {//相当于三孔插座
    //普通功能
    public void request();
}
 

//已存在的、具有特殊功能、但不符合我们既有的标准接口的类  
public class Adaptee {
  public void specificRequest() {
      System.out.println("被适配类...我是两孔插座  具有特殊功能");
  }
}
 
public class Client {
    public static void main(String[] args) {
        //使用特殊功能类,即适配类, 需要先创建一个被适配类的对象作为参数
 
        Target adapter = new Adapter(new Adaptee());  //父类引用指向子类对象
        adapter.request();  
    }

/*适配器类,直接关联被适配类,同时实现标准接口  
*充当适配器角色的类就是:继承已有接口的抽象类
*为什么要用抽象类呢:此类是不要被实例化的。而只充当适配器的角色,也就是为其子类提供了一个共同的接口。
*但是又可以将精力只集中在其感兴趣的地方。
*/
class Adapter implements Target {
  // 直接关联被适配类
  private Adaptee adaptee; 
  // 可以通过构造函数传入具体需要适配的被适配类对象
  public Adapter(Adaptee adaptee) { 
  //也就是说,Adapter自身必须先拥有一个被适配类的对象,再把对象的特殊功能委托给这个对象来实现。
      this.adaptee = adaptee;
  }
@override  
  public void request() {
      // 这里是使用委托的方式完成特殊功能  即没有共同的接口
      System.out.println("我是适配器类 我能适配任何两孔插座 让它正常工作");
      this.adaptee.specificRequest();
  }
}

类适配器:

package test1;
//目标接口,或称为标准接口
public interface Target {
//普通方法
   public void request();
}

public class Adaptee {
public void spacificRequest(){
         System.out.println("被适配类,我是两孔插座,具有特殊功能");
}
}

public class Client {
 public static void main(String[] args) {
Target adapter =new Adapter();

adapter.request();
}
}
 

public class Adapter extends Adaptee  implements Target {
//采用继承实现的一个适配器模式
@Override
public void request() {
 System.out.println("我是适配器类,我能适配任何的两孔插座,让他工作");
 this.spacificRequest();
}
}

如何做到一个类不被实例化或者不被轻易实例化?

1.把一个类定义为抽象类;
2.把一个类的构造方法设置为:private类型的,这样在客户端就不能通过new ClassName()方法来轻易将一个类实例化,而是生成此类的实例就必须通过一个特殊的方法,这样在一个系统中,对此类的使用 就能得到合理的控制。(如单例模式/多例模式/工厂模式等)

对象适配器&类适配器对比

从代码中我们可以也知道需要修改 的只不过是Adapter类中的内部结构,即Adapter自身必须先拥有一个被适配的对象(相当于二孔插头)再把具体的特殊功能委托给这个对象来实现。使用对象适配器模  式,可以使得Adapter类(适配器)根据传入的Adaptee对象达到适配多个不同被适配类的功能,当然,此时我们可以为多个被适配类提取一个接口或多个抽象类。这样看起来的话,似乎对象适配器更加灵活一些。对于类适器仅引用了一个对象,并不需要额外的引用来间接得到Adaptee.对于类适配器,需要额外的引用来间接得到Adaptee.

模式总结:
优点:
1.通过适配器,客户端可以直接调用同一接口,因而对客户端来说是透明的。这样做更简单,更直接,更紧凑。
2.复用了现存的类,解决了现存类和复用环境要求不一致的问题。
3.将目标类和适配者类解耦,通过引入一个适配器现有的适配者类,而无须修改原有代码。
一个对象适配器可以把多个不同的适配器类适配到同一个目标,也就是说,同一个适配器可以把适配者类和他的子类都适配到目标接口。
缺点:
1.对于适配器来说,更换适配器的实现过程比较复杂 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息