适配器模式——不同接口的适配


Demo 地址: https://github.com/ooblee/HelloDesignPattern

1. 定义

适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

类似电源适配器、转接口、转换器等,解决两者接口不匹配或结构不兼容的问题。

2. 设计

主要角色:

  • 目标类(Target),定义客户需要的接口。可以是抽象类或者接口,或者具体类。
  • 被适配类(Adaptee),定义需要适配的接口。一般为具体类。
  • 适配器类(Adapter),继承目标,引用被适配类,对目标和被适配类进行适配。也可以都采用继承的方式。

类图如下:

适配器模式-类图

具体有这几种实现:

  • 继承方式,类适配器。
  • 组合方式,对象适配器。
  • 接口的默认空实现,接口适配器。

2.1. 类适配器

通过 继承 来实现适配功能。

目标接口,定义要转换后的接口。

public interface Target {

    void request();
}

适配者类,定义要被转换的接口。

public class Adaptee {

    public void adapteeRequest() {
        System.out.println("adaptee Request");
    }
}

适配器,像变魔术一样接口转换。

public class Adapter extends Adaptee implements Target {

    public void request() {
        adapteeRequest();
    }
}

客户端使用对比:

public class TestAdapter {

    public static void main(String[] args) {

        // 适配前的接口
        Adaptee adaptee = new Adaptee();
        adaptee.adapteeRequest();

        // 适配后的接口
        Target target = new Adapter();
        target.request();

    }
}

2.2. 对象适配器

通过 组合 来实现适配功能。

把上面的 Adapter 改造一下,不再使用继承,而是让 Adaptee 作为成员变量:

public class Adapter implements Target {

    public Adaptee adaptee = new Adaptee();

    public void request() {
        adaptee.adapteeRequest();
    }
}

2.3. 接口适配器

接口模式的适配器,其实是对需要实现方法很多的接口提供一个默认的空实现。

如果使用的方法很多,但应用的时候只需要部分方法的情况下,可以只实现部分方法。

比如有个监听器定义了一堆方法:

public interface Listener {

    void sayYes();

    void sayNo();

    void sayHello();

    void sayGoodBye();

    void sayHappy();

    void saySad();

    void sayHi();
}

客户使用的时候,只关心 sayHello 的监听。

创建一个 Listener 的 Adapter:

public class ListenerAdapter implements Listener {

    public void sayYes() {

    }

    public void sayNo() {

    }

    public void sayHello() {

    }

    public void sayGoodBye() {

    }

    public void sayHappy() {

    }

    public void saySad() {

    }

    public void sayHi() {

    }
}

然后使用的时候,就可以只实现调用者关心的回调函数了。

public class TestAdapter {

    public static void main(String[] args) {
        Listener listener = new ListenerAdapter() {
            @Override
            public void sayHello() {
                System.out.println("hello.");
            }
        };

        listener.sayHello();
    }
}

3. 应用

应用场景:

  • 要使用一些系统原有的类,但接口不满足当前设计。
  • 要创建一个可重复使用的类,相对独立,和其他类没有太大关联,同时未来还会继续扩展和修改。

3.1. JDK:Executors 的 RunnableAdapter

3.2. JDK:InputStreamReader 和 OutputStreamWriter

4. 特点

4.1. 优势

  • 解耦。目标类与适配者解耦。两者独立发展,互不影响。
  • 易复用。一个适配者可以多个不同的系统中复用。
  • 易扩展。可以不修改原本代码的情况下增加适配者,也可以通过配置文件指定。符合开闭原则。

4.2. 缺点

  • 类适配
    • 不支持多重继承的语言,不能同时适配多个适配者.
    • 适配者不能成为最终类。
  • 对象适配,置换适配者比较复杂。
发布了61 篇原创文章 · 获赞 43 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/firefile/article/details/90313967
今日推荐