适配器模式(Adapter Pattern) – 设计模式之结构型模式:
目录
适配器模式(Adapter Pattern)
定义: Convert the interface of a class info another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. (将一个类的接口变换成客户
端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作)
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
在软件开发中,当系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控制范围外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致又不容易修改的时候的情况。 类适配器模式 和 对象适配器模式
意图:将接口转换成不同的接口
将一个接口转换成另一个接口,将一个不兼容的对象包装起来,变成兼容的对象。
类图
适配器模式通用类图:
例子-充电接口:
过程:
在生活中,手机充电很多就的手机是Micro接口的
苹果手机的接口是 Lightning接口的:
新的手机很多是TypeC的,支持快充:
TypeC的充电器坏了, 还有其他接口的充电线,这时候该怎么处理呢?
这时候需要一个适配器,插入适配器后,其它的接口就可以用TypeC的充电了。
类图:
代码:
充电接口 Charging
public interface Charging {
void charging(); // 充电
}
普通接口 MicroUSB
public class MicroUSB implements Charging {
@Override
public void charging() {
System.out.println("可以给Micro USB接口接口的电子产品充电");
}
}
TypeC接口
public class TypeC implements Charging {
@Override
public void charging() {
System.out.println("可以给TypeC接口的电子产品充电");
}
}
苹果接口 Lightning
public class Lightning implements Charging {
@Override
public void charging() {
System.out.println("可以给Lightning接口接口的苹果电子产品充电");
}
}
普通接口适配TypeC MicroUSBAdapter
适配器模式的核心角色,其他两个角色都是已经存在的角色,而适配器角色是需要新建立的,它的职责非常简单:把源角色转换为目标角色,怎么转换?通过继承或是类关联的方式。
public class MicroUSBAdapter implements Charging {
private TypeC plug;
//创建适配器地时候,需要把TypeC接入进来
public MicroUSBAdapter(TypeC plug) {
this.plug = plug;
}
@Override
public void charging() { //重写原有接口中的方法,从而实现接口转化
System.out.println("通过适配器转化");
plug.charging();
}
}
苹果接口适配TypeC LightningAdapter
public class LightningAdapter implements Charging {
private TypeC plug;
public LightningAdapter(TypeC plug) {
this.plug = plug;
}
@Override
public void charging() {//重写原有接口中的方法,从而实现接口转化
System.out.println("通过适配器转化");
plug.charging();
}
}
测试:
public class ChargingAdapterTest {
public static void main(String[] args) {
TypeC typeC = new TypeC();
System.out.println("========= 充电器是Micro USB接口的 ========");
Charging typec = new MicroUSBAdapter(typeC);//这里就是通过适配器实现转换
typec.charging();
System.out.println("========= 充电器是Lightning接口的 ========");
Charging lightning = new LightningAdapter(typeC);//这里就是通过适配器实现转换
lightning.charging();
}
}
结果:
========= 充电器是Micro USB接口的 ========
通过适配器转化
可以给TypeC接口的电子产品充电
========= 充电器是Lightning接口的 ========
通过适配器转化
可以给TypeC接口的电子产品充电
分析
适配器模式主要是在 适配器角色 Adapter 类中引用需要适配的对象,进行适配的。
总结:
优点:
1、可以让任何两个没有关联的类一起运行。
2、提高了类的复用。
3、增加了类的透明度。
4、灵活性好。
缺点:
1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
使用场景
适配器应用的场景只要记住一点就足够了:你有动机修改一个已经投产中的接口时,适配器模式可能是最适合你的模式。比如系统扩展了,需要使用一个已有或新建立的类,但这个类又不符合系统的接口,怎么办?使用适配器模式,这也是我们例子中提到的。
项目一定要遵守依赖倒置原则和里氏替换原则