设计模式之适配器模式

目录

一、定义

二、结构

三、代码实现

1、耳机适配器例子

2、耳机充电器适配器例子

四、特点

1、类适配器和对象适配器的对比

五、适用环境


在很久很久以前,耳机几乎都是3.5mm的接口,大部分电子设备耳机的插孔也都是3.5mm。大家一直都遵循这个规则。突然有一天,苹果跳出来说,我的手机不要3.5mm的耳机接口了,充电接口就是耳机接口。我们的耳机也会做成相应的插孔。

这下大家就傻了。我耳机都是3.5mm的接口,你苹果产品不能用这些耳机了,这不是玩呢吗?苹果这一举措导致了Iphone7以后的产品都无法正常使用3.5mm接口了。

耳机大厂就开骂了,我不可能为了你苹果就修改我的耳机接口啊。所以这时候就出现了一个东西,转换器

苹果耳机转换器能将3.5mm的耳机用在苹果设备上,达到了一个适配的功能。

一、定义

适配器模式:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。

文章开头的例子,就是一个典型的适配器模式。他对原本不兼容的3.5mm耳机和苹果设备做了适配,使他们可以正常使用。

二、结构

适配器模式有三个角色:

  1. Target(目标抽象类):这个接口定义了客户所需要的功能。在前面的例子中,target就是转换器。

  2. Adapter(适配器):这是target的具体实现类,定义了具体怎么适配。在前面的例子中,adapter是苹果耳机转换器。

  3. Adaptee(适配者):这是Adapter要适配的东西。在前面的例子中,Adaptee是耳机。

三、代码实现

1、耳机适配器例子

首先我们来写一个耳机类。耳机的作用就是播放声音。

public class Earphone {
​
    public void playSound() {
        System.out.println("耳机播放声音");
    }
​
}

然后定义一个耳机适配器的接口,作用就是适配各种耳机

public interface EarPhoneAdapter {
​
    void adaption();
    
}

然后,就是一个具体的适配器。将普通耳机适配到IOS设备。

public class ToIosAdapter extends Earphone implements EarPhoneAdapter{
​
    @Override
    public void adaption() {
        System.out.println("使用转换器适配到苹果手机");
        super.playSound();
    }
    
}

注意这里,我们通过继承Earphone来达到适配的效果。这种继承方式的适配器叫做类适配器。

但是,由于Java单继承的特性,类适配器就只能适配一个类,有一定的局限性。后面我们会再说到通过组合方式的对象适配器。

这时候我们就可以正常使用转换器了

public class Client {
​
    public static void main(String[] args) {
        EarPhoneAdapter adapter = new ToIosAdapter();
        adapter.adaption();
    }
    
}
​

运行结果:

 

然后众所周知,后来华为也取消了3.5mm耳机孔,也和充电孔共用了。这时候我们要添加Type-C的适配器,也无需修改原本的代码,新增一个新的适配器就好,符合开闭原则

2、耳机充电器适配器例子

虽然耳机适配器已经能满足大部分用户的需求。但是还是有用户不满,我以前能同时用耳机听歌和充电,现在你就一个孔,让我怎么同时做两件事。没关系,我们就出一个能满足两个需求的适配器。

我们新添加一个充电器类

public class Charger {
    
    public void charge() {
        System.out.println("开始充电");
    }
    
}

这时候,用户的对适配器的要求就是既能插耳机听歌,又能充电。所以我们来一个强大的适配器接口。

public interface StrongAdapter {
​
    void playSoundWithEarphone();
    
    void charge();
​
}
​

最后实现一个转TypeC的适配器

public class ToTypeCAdapter implements StrongAdapter{
​
    private Earphone earphone;
    private Charger charger;
​
    public ToTypeCAdapter(Earphone earphone, Charger charger) {
        this.earphone = earphone;
        this.charger = charger;
    }
​
    @Override
    public void playSoundWithEarphone() {
        earphone.playSound();
    }
​
    @Override
    public void charge() {
        charger.charge();
    }
    
}

这里我们不再使用继承,而是使用了组合的方式,这种适配器叫对象适配器。

对象适配器的好处在于,可以适配多个类,更加灵活

然后用户就可以又充电又听歌了。

public class Client {
​
    public static void main(String[] args) {
        Earphone earphone = new Earphone();
        Charger charger = new Charger();
​
        StrongAdapter adapter = new ToTypeCAdapter(earphone, charger);
        adapter.playSoundWithEarphone();
        adapter.charge();
    }
}

运行结果:

 

四、特点

  • 使用适配器模式可以提高类的复用性,比如耳机厂商不必去生产IOS接口和Type-C插孔的耳机。并且需要新的具体适配器时,无需修改原本的代码,只用新增,符合开闭原则。

1、类适配器和对象适配器的对比

因为Java单继承的特性,类适配器仅能适配一个类。并且抽象适配器只能是一个接口

而对象适配器采用组合的方式,能够灵活的适配多个类。并且因为没有使用继承,此时的抽象适配器可以是接口,也可以是一个抽象类,可以实现一些公共的方法。并且根据“里氏替换原则”, 适配器还可以适配适配者的子类

五、适用环境

在系统需要使用一些现有的类,而这些类不符合系统要求,需要适配转换的时候可以使用适配器模式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值