设计模式学习5——适配器模式

概述

记录了适配器模式的概念以及代码实现

定义

设计模式学习5——适配器模式_第1张图片
简单来说,适配器模式就是要将一个接口转换成另一个接口,大多数情况都是功能扩展之后用了新的接口,但是底层还是用的过去的接口,需要将新的接口转换成旧的才能使用。
例如我们用的充电器也是一种适配器。下面我会以翻译作为例子来说明适配器模式。

类图

设计模式学习5——适配器模式_第2张图片
当马布里来中国打球的时候,他并不会说中文,所以讲战术只能说英文那么就需要翻译,翻译也相当于是一个适配器。
Target:说中文战术
Adapter:翻译(适配器)
Adeptee:要适配的类(说英文战术)
翻译就是吧英文翻译成中文。
适配器有类适配器和对象适配器两种,下面详细介绍。

类适配器

还是用上面翻译的例子,现在我的需求是把说英文的接口转换成说中文的。

下面的类就是需要适配的,他现在只会说英文战术

interface SpeakEnglish {
    void speakEnglish(String name, String tactics);
}
//需要适配的类
public class ForeignPlayer implements SpeakEnglish {

    @Override
    public void speakEnglish(String name, String tactics) {
        System.out.println(name + "说英文:" + tactics + "战术");
    }
}

目标:

interface SpeakChinese {
    void speakChinese(String name,String tactics);
}

public class NativePlayer implements SpeakChinese{
    @Override
    public void speakChinese(String name, String tactics) {
        System.out.println(name+"说中文:"+tactics+"战术");
    }
}

类适配器使用继承实现适配器

public class Adapter extends ForeignPlayer implements SpeakChinese {
    @Override
    public void speakChinese(String name, String tactics) {
        super.speakEnglish(name,tactics);
        System.out.println("翻译成了中文");
    }
}

Client

public class Client {
    public static void main(String[] args) {
        SpeakEnglish foreignPlayer = new ForeignPlayer();
        SpeakChinese adapter = new Adapter();
        adapter.speakChinese("马布里","二三联防");
    }
}

这样,就从SpeakEnglish转换成了SpeakChinese接口
设计模式学习5——适配器模式_第3张图片

但是实际上这里使用继承实现的
不满足合成复用原则的:尽量使用对象组合,而不是继承来达到复用的目的。
所以下面改进一下,实现对象适配器

对象适配器

使用组合而非继承。要修改的地方并不多:
修改适配器

public class Adapter implements SpeakChinese{
    private SpeakEnglish foreignPlayer;
    public Adapter(SpeakEnglish foreignPlayer) {
        this.foreignPlayer=foreignPlayer;
    }
    @Override
    public void speakChinese(String name, String tactics) {
        foreignPlayer.speakEnglish(name,tactics);
        System.out.println("翻译成了中文");
    }
}

Client:

public class Client {
    public static void main(String[] args) {
        SpeakEnglish foreignPlayer = new ForeignPlayer();
        SpeakChinese adapter = new Adapter(foreignPlayer);
        adapter.speakChinese("马布里","二三联防");
    }
}

设计模式学习5——适配器模式_第4张图片

使用场景

  1. 两个类所做的事情相同或相似,但是具有不同的接口时使用
  2. 系统发展,产生了功能类似但是不同的接口时使用
  3. 所以适配器大多是无奈之举
  4. SpringMVC中HandlerAdapter
  5. AOP中所有的通知都会转化成环绕通知,转化的事Interceptor接口,这里就是用的也是适配器模式。

优点

  1. 提高了代码的复用性,不需要重新写代码,通过适配器就重用已有代码
  2. 解决目标类和适配者类不一致的问题
  3. 能让客户端透明访问目标接口

小结

只有写代码才知道自己是不是真的会了,中间出了好多小问题,比如接口类型只能调用接口类型的方法,继承父类是得不到实例化对象的属性值,实例对象和类完全是两码事。

你可能感兴趣的:(设计模式,学习,适配器模式)