设计模式之适配器模式

介绍

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作

来自百度百科。

什么意思呢?举个例子:

有一个三孔插座,但是你的电脑只支持两孔插座来充电,这个时候你就需要一个电源适配器来使电脑能够在这个三孔插座上充电。

适配器模式属于结构型模式。

维基百科:
In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.
在软件工程中,适配器模式是一种软件设计模式可以允许将一个已存在的类接口用作另一个接口。它通常用于使现有类与其他类一起工作,而无需修改它们的源代码。

适配器模式又分为:

  • 类适配器模式
  • 对象适配器模式

案例

对象适配器模式

首先,定义两个接口:SpeakChineseSpeakEnglish,并创建其实现类。

public interface SpeakChinese {
    void speak();
}
public class SpeakChineseImpl implements SpeakChinese {
    @Override
    public void speak() {
        System.out.println("说中文");
    }
}
public interface SpeakEnglish {
    void speak();
}
public class SpeakEnglishImpl implements SpeakEnglish{
    @Override
    public void speak() {
        System.out.println("speak english");
    }
}

现在存在一个Person,它是一个中国人只会说中文。

public class Person {
	
    private final SpeakChinese speakChinese;
	
	// 只会说中文的中国人
    public Person(SpeakChinese speakChinese) {
        this.speakChinese = speakChinese;
    }

    public void speak() {
        speakChinese.speak();
    }

}

Test:

Person person01 = new Person(new SpeakChineseImpl());
person01.speak();	// 说中文

这个时候,突然来一个老外问路,但是他又不会将英文,咋办?

只好创建一个适配器:SpeakEnglishAdapter,使这个人也能够讲英文。

public class SpeakEnglishAdapter implements SpeakChinese {

    private final SpeakEnglish speakEnglish;

    public SpeakEnglishAdapter() {
        this.speakEnglish = new SpeakEnglishImpl();
    }

    @Override
    public void speak() {
        speakEnglish.speak();
    }
}

Test:

Person person02 = new Person(new SpeakEnglishAdapter());
person02.speak();	// speak english

可以发现,我们并没有去修改原来的代码,只是增加了一个适配器即可完成我们需要的功能。

类适配器模式

这种方式唯一的不同就是SpeakEnglishAdapter中使用继承的方式去调用适配者的方法。

public class SpeakEnglishAdapter extends SpeakEnglishImpl implements SpeakChinese {
    @Override
    public void speak() {
        super.speak();
    }
}

可以发现,这种方式的耦合度比对象适配器模式要高很多,在实际中也不常用这种方式去实现。

一个典型的源码案例 FutureTask

FutureTask两个构造方法
在这里插入图片描述
可以看到,它允许我们传入CallableRunnable去构造一个FutureTask对象,但是再看看构造方法的内部,即使我们传入的对象是Runnable对象,它还是会去构造一个Callable类型的对象封装到属性中,换句话说,FutureTask类只能适配Callable对象。
在这里插入图片描述
所以,这个时候必须要去创建一个适配器,使FutureTask对象也能够适配Runnable,来看看Executors.callable(runnable, result)方法的内部。在这里插入图片描述
具体看看RunnableAdapter,很经典的适配器实现方式
在这里插入图片描述
最后使得this.callable能够接收RunnableAdapter
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值