《设计模式》-- 适配器模式

来源:互联网 发布:linux下串口调试助手 编辑:程序博客网 时间:2024/05/15 14:41

适配器模式

  • 适配器模式
    • 认识
    • 思考
    • 使用场景
    • 优缺点
    • UML图
      • 类适配器
      • 对象适配器
      • 缺省适配
    • 代码实现
      • 类适配器
      • 对象适配器
      • 缺省适配

认识

适配器模式是将一个类的接口变为客户端想要的另外一个接口,从而使原本因接口不匹配无法在一起工作的两个类能够在一起工作。适配器的目的是复用已有的功能。

适配器分为类适配器对象适配器两种

缺省适配:为一个接口提供缺省实现,一般是一个抽象类

适配器模式跟代理模式的不同之处:适配器模式中适配器和被适配对象中的接口方法不一致,适配器对被适配对象中的接口进行了改造或者扩展。代理模式中代理对象和被代理对象实现同一个接口,可以相互替换,代理对象只是对被代理对象中接口方法中的逻辑进行了改变,如添加权限控制。

思考

适配器模式可以对一个接口的所有子类进行适配,对象适配器中持有一个父类指针。不需要单独去对每个子类建立适配器。

适配器模式实质:转换接口,复用功能,通过适配器将老的接口实现类中的方法转换为新的接口中的方法

优先使用对象适配器,多用合成/聚合,少用继承。

使用场景

如果定义了新的接口跟已存在一个实现类不兼容,但是又在新的接口中又想使用实现类中方法,这时使用适配器模式实现复用实现类中的功能。

优缺点

  • 优点

    1. 更好的复用性:能够兼容使用老的接口
    2. 开闭原则:避免了对老接口的修改,通过添加适配器实现兼容,达到更好的扩展性
  • 缺点

    1. 过多的使用适配器模式,会导致调用零乱,明明调用A接口,在A接口中实际调用的是B接口,脱离控制。如果不是很有必要,可以不使用适配器,而是对系统进行重构。

UML图

类适配器:

采用继承方式,即适配器继承被适配类

image

  • 目标接口(Target):客户端真正想要的接口
  • 被适配接口(Adaptee):已有的接口实现类,与客户端最新需要的接口不兼容
  • 适配器(Adapter):适配器,实现Target和继承Adaptee,客户端调动Adapter,既可以调用Target中的接口方法,也可以调用Adapter继承Adaptee中老的方法

对象适配器:

使用对象动态组合方式,即适配器持有一个被适配对象

image

  • 目标接口(Target):客户端真正想要的接口
  • 被适配接口(Adaptee):已有的接口实现类,与客户端最新需要的接口不兼容
  • 适配器(Adapter):适配器,实现Target,持有一个Adaptee对象,对于新的接口,调用Adapter中实现的方法,对于老的方法,使用Adaptee对象进行调用

缺省适配

很多情况下,接口中定义了特别多方法,而一个类去实现一个接口,必须要实现所有的方法,但是有些类只是使用到了接口中很少的方法,对于不使用的方法就只能空着,这样会对客户端的调用造成困扰。这时就需要使用一个抽象类去实现接口,在抽象类中给出所有方法的”平庸”实现。从这个抽象类再继承下去的子类就不必实现所有的方法了。,在java源码中很多地方都使用到了这种处理,如List中等。缺省适配的用意是为了避免子类去处理自己不关注的接口方法

image

代码实现

类适配器:

适配器继承被适配对象,实现目标接口,客户端使用适配器进行调用,对于目标接口中新的方法,适配器进行实现,对于老的接口方法,调用适配器继承而来的被适配类中的方法,从而实现接口兼容。

/** * 客户端需要的接口 */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() {        //写相关的代码    }}

对象适配器:

适配器实现目标对象,通过构造方法持有一个被适配对象,客户端使用适配器进行调用,对于新的接口调用适配器中的方法,对于老的接口实现,适配器使用被适配对象调用被适配对象中的方法,从而实现接口兼容。

/** * 客户端需要的接口 */public interface Target {    public void request1();    public void request2();}/** * 已经存在的接口,这个接口需要被适配 */public class Adaptee {    /**     * 示意方法,原本已经存在,已经实现的方法     */    public void request1() {        //具体的功能处理    }}/** * 适配器 */public class Adapter implements Target {    /**     * 持有需要被适配的接口对象     */    private Adaptee adaptee;    /**     * 构造方法,传入需要被适配的对象     * @param adaptee 需要被适配的对象     */    public Adapter(Adaptee adaptee) {        this.adaptee = adaptee;    }    public void request1() {        //可能转调已经实现了的方法,进行适配        adaptee.request1();    }    public void request2() {        //业务代码    }}/** * 使用适配器的客户端 */public class Client {       public static void main(String[] args) {        //创建需被适配的对象        Adaptee adaptee = new Adaptee();        //创建客户端需要调用的接口对象        Target target = new Adapter(adaptee);        //请求处理        target.request();    }}

缺省适配:

使用抽象类实现接口,对接口中方法进行默认实现。

0 0
原创粉丝点击