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

概述

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

定义

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

类图

在这里插入图片描述
当马布里来中国打球的时候,他并不会说中文,所以讲战术只能说英文那么就需要翻译,翻译也相当于是一个适配器。
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接口
在这里插入图片描述

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

对象适配器

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

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("马布里","二三联防");
    }
}

在这里插入图片描述

使用场景

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

优点

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

小结

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值