一天一个设计模式:适配器模式

概念:

  适配器模式是把一个类的接口变成客户端所期待的另外一种接口,从而使本来因接口不匹配而没法在一块儿工做的两个类可以在一块儿工做。api

用途:

  就像插头转换器,以前入了switch港版,插头是英式的,还好附赠一个插头转换器,适配器就至关于这个转换器。ide

种类:

  分为类的适配器与对象的适配器两种this

 

类适配器:

  把适配的类的api转化为目标类的apispa

上图中Adaptee没有2方法,可是客户端却指望调用2方法。为了客户端可以使用Adaptee类,提供中间类Adapter,把Adaptee与Target的api组合起来,Adapter与Adaptee是继承关系,因此这决定了适配器是类适配器。code

涉及到的角色:对象

  目标(Target)角色:这就是所期待获得的接口。注意:因为这里讨论的是类适配器,所以目标不能是类。blog

  源(Adapee)角色:如今须要适配的接口。继承

  适配器(Adapter)角色:适配器类是本模式的核心。适配器把源接口转化成目标接口,显然这一角色不能够是接口必须是具体类。接口

类适配器代码:get

public interface Target {
    /**
     * 这是源类Adaptee也有的方法
     */
    public void sampleOperation1(); 
    /**
     * 这是源类Adapteee没有的方法
     */
    public void sampleOperation2(); 
}
public class Adaptee {
    
    public void sampleOperation1(){}

}
public class Adapter extends Adaptee implements Target {
    /**
     * 因为源类Adaptee没有方法sampleOperation2()
     * 所以适配器补充上这个方法
     */
    @Override
    public void sampleOperation2() {
        //写相关的代码
    }

}

适配器Adapter扩展了源类,也实现了目标接口,且提供了源类没有的接口的实现。


 

对象适配器模式

  对象适配器与类适配器不一样的地方在于,对象适配器采用委派的方式将源类与适配器关联到一块儿(类适配器采用继承)

 

 

源代码:

 

public interface Target {
    /**
     * 这是源类Adaptee也有的方法
     */
    public void sampleOperation1(); 
    /**
     * 这是源类Adapteee没有的方法
     */
    public void sampleOperation2(); 
}

 

public class Adaptee {

    public void sampleOperation1(){}
    
}
public class Adapter {
    private Adaptee adaptee;
    
    public Adapter(Adaptee adaptee){
        this.adaptee = adaptee;
    }
    /**
     * 源类Adaptee有方法sampleOperation1
     * 所以适配器类直接委派便可
     */
    public void sampleOperation1(){
        this.adaptee.sampleOperation1();
    }
    /**
     * 源类Adaptee没有方法sampleOperation2
     * 所以由适配器类须要补充此方法
     */
    public void sampleOperation2(){
        //写相关的代码
    }
}

类适配器与对象适配器的权衡

 

  • 类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用的是对象组合的方式,是动态组合的方式。
  • 对于类适配器,因为适配器直接继承了Adaptee,使得适配器不能和Adaptee的子类一块儿工做,由于继承是静态的,当适配器继承Adaptee后,就不能再处理,Adaptee的子类。
  • 对于对象适配器,一个适配器能够把不一样的源类适配到同一个目标中,换一种说法,同一个适配器能够把源类和它的子类都适配到目标接口。由于对象适配器采用的是对象组合的关系,只要类型正确,是否是子类都无所谓。
  • 对于类适配器,适配器能够重定义部分Adaptee的部分行为,至关于子类覆盖父类的方法。
  • 对于对象适配器,要从新定义源类的的行为很困难,这种状况下,须要定义Adaptee的子类来实现重定义,而后让适配器从新适配,虽然重定义Adaptee比较困难,可是想要增长一些新的行为则很方便,并且新增的行为能够适配全部的源。
  • 对于类适配器,仅仅引入了一个对象,并不须要额外的引用来间接获得Adaptee。
  • 对于对象适配器,须要额外的引用来简介获得Adaptee。

综上,尽可能以对象适配器的实现方式为主,多用聚合,少用继承。固然具体问题具体分析,根据实际须要选择(我的认为实际上就不必对源类进行重写,若是须要进行重写直接对源类进行修改就好了,除非是没有代码权限,不过若是没有权限的话,那么源类对你来说更不可见,也就更没有重写的必要了吧。)。

适配器的优势:

  更好的复用性:

    系统须要使用现有的类,而此类的接口不符合系统的须要,那么经过适配器模式可让类得到更好的复用。

  更好的扩展性:

    在适配器实现功能的时候,也能够调用本身的功能,从而扩展系统的功能。

适配器的缺点:

  过多的适配器,会让系统显得更加凌乱,不容易把控。

  重构的代价合适的话,确实要比适配器更合适。

相关文章
相关标签/搜索