JDK与设计模式:适配器模式

  1、适配器模式  
      适配器模式可以将一个类的接口和另一个类的接口匹配起来。适配器模式将一个接口转换为客户希望的另一个接口,使接口不兼容的哪些类可以一起工作,其别名是包装器。适配器模式既可以作为类结构模型,也可作为对象结构模型。
       在适配器模式中,我们通过增加一个新的适配器类来解决接口不兼容的问题,使得原本没有任何关系的类可以协同工作。根据适配器类与适配者类的关系不同,适配器模式可分为对象适配器和类适配器两种, 在对象适配器模式中,适配器与适配者之间是关联关系;在类适配器模式中,适配器与适配者之间是继承(或实现)关系。
组成:
  1)ClientTarget(目标抽象类):目标抽象类定义客户所需接口,可以是一个抽象类或接口,也可以是具体类。

  2)Adapter(适配器类):适配器可以调用另一个接口,作为一个转换器,对AdapteeTarget进行适配,适配器类是适配器模式的核心,在对象适配器中,它通过继承Target并关联一个Adaptee对象使二者产生联系。

  3)AdapteeTarget(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下可能没有适配者类的源代码。

类图:

         

    根据对象适配器模式结构图,在对象适配器中,客户端需要调用ClientTarget(客户目标抽象类)的request()方法,而适配者类AdapteeTarget没有该方法,但是它所提供的specificRequest()方法却是客户端所需要的。为了使客户端能够使用适配者类,需要提供一个包装类Adapter,即适配器类。这个包装类包装了一个适配者的实例,从而将客户端与适配者衔接起来,在适配器的request()方法中调用适配者的specificRequest()方法。因为适配器类与适配者类是关联关系(也可称之为委派关系),所以这种适配器模式称为对象适配器模式。

代码:

  

   abstract class ClientTarget{
   protected void request(){
   }
 }   
    class AdapteeTarget{           
     public	AdapteeTarget(){     
  }
     void	specialcRequect(){  
     }    
 }   
 class Adapter  extends ClientTarget{
  private AdapteeTarget adaptee ;
  public Adapter(AdapteeTarget adaptee){
   this.adaptee = adaptee;
  }
  @Override
  protected void request() {
   // TODO Auto-generated method stub
   adaptee.specialcRequect();
  }   
 }


     除了对象适配器模式之外,适配器模式还有一种形式,那就是类适配器模式,类适配器模式和对象适配器模式最大的区别在于适配器和适配者之间的关系不同,对象适配器模式中适配器和适配者之间是关联关系,而类适配器模式中适配器和适配者是继承关系。

适用场景:系统需要使用一些现有的类,而这些类的接口(如方法名)不符合系统的需要,甚至没有这些类的源代码。

总结:适配器模式将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构,  增加了类的透明性和复用性。 


2、JDK中适配器模式应用

      在java jdk中,适配器模式使用场景很多,如集合包中java.util.Arrays#asList()、io包中java.io.InputStreamReader(InputStream)、java.io.OutputStreamWriter(OutputStream) 等。


Reader 类对应ClientTarget抽象类,InputStreamReader 类对应Adapter类,  InputStream 对应AdapteeTarget。InputStreamReader 将Reader 接口和InputStream 接口适配起来。

   public class InputStreamReader extends Reader {
    private final StreamDecoder sd;
//构造函数,传入InputStream 对象in,并且关联在StreamDecoder sd对象中,
    public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
            // The default encoding should always be available
            throw new Error(e);
        }
    }

 //适配Reader 接口中字符读取操作,调用sd中字节读取转化为字符读取。
    public int read() throws IOException {
        return sd.read();
    }


}





   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值