背景
模式定义:
把一个类的接口,变换成客户端所期待的另一种接口,从而使原来因接口不匹配而无法一起工作的两个类能够一起工作,又称为转换器模式、变压器模式、包装模式。
我突然明白了,为什么官方的解释总是那么地抽象,很多时候难以理解。大概是因为他们不仅要从众多的例子中抽象出一个概念,更要适用所有情形。好吧,真是难为他们了。
情景
现在有220V的电源,你有12v的笔记本电脑需要充电,但是你没有12v的电源。这时候你需要一个适配器,把220v电源输出的电流转为12v的电流。
220V的电源接口类和实现类(面向接口编程):
/**
* 描述:220v电源接口
* <p>作者: aliyu
* <p>创建时间: 2021-10-20 9:22 上午
*/
public interface power220v {
/**
* 输出220v的电流
*/
void outPut220v();
}
/**
* 描述:220v电源实现类
* <p>作者: aliyu
* <p>创建时间: 2021-10-20 9:59 上午
*/
public class power220vImpl implements power220v{
/**
* 执行这个方法就会输出220v的电流
*/
@Override
public void outPut220v() {
System.out.println("正在输出220v电流....");
}
}
12v的电源接口:
* 描述:12v电源接口
* <p>作者: aliyu
* <p>创建时间: 2021-10-20 9:25 上午
*/
public interface power12v {
/**
* 输出12v电流
*/
void outPut12v();
}
类图结构:
这样适配源(220v电源接口和实现),以及适配目标接口都有了(你问为啥没有12v的实现?有了实现就是有12v的电源啊,那还做什么适配?!)
接下来我们开始做适配器。
对象适配器
适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用它包裹对象的物理实体。
适配器代码:
public class ObjectAdapter implements Power12v{
/**
* 220v的电源(转换原料的生产者)
*/
private Power220vImpl power220vImpl;
public ObjectAdapter(Power220vImpl power220vImpl) {
this.power220vImpl = power220vImpl;
}
@Override
public void outPut12v() {
//转换第一步,把220v的电流输出来(转换总得有原材料吧)
power220vImpl.outPut220v();
//模拟转换的过程
System.out.println("开始转换220v的电流为12v....");
//模拟输出转好的电流
System.out.println("转换成功,输出转好的12v电流!!!...");
}
}
ps:首先适配器类(ObjectAdapter)实现了12v电源的接口(Power12v),这样适配器就拥有了可以输出12v电流的方法。当适配器开始工作时(初始化),插入220v的电源(引入power220vImpl对象)作为原料。适配器方法“outPut12v”中:先调用220v电源产生220v电流(作为原料),然后进行转换,最后输出12v电流的过程。
类关系图:
ps:可以看出它们是组合的方式。
测试代码:
/**
* 描述:测试对象适配器模式
* <p>作者: aliyu
* <p>创建时间: 2021-10-20 11:20 上午
*/
public class TestObjectAdapter {
public static void main(String[] args) {
//准备220v的电源
Power220vImpl power220vImpl = new Power220vImpl();
//接上适配器
ObjectAdapter objectAdapter = new ObjectAdapter(power220vImpl);
//输出12v电流
objectAdapter.outPut12v();
}
}
类适配器
类适配器代码:
/**
* 描述:类适配器模式
* <p>作者: aliyu
* <p>创建时间: 2021-10-20 11:33 上午
*/
public class ClassAdapter extends Power220vImpl implements Power12v{
@Override
public void outPut12v() {
//先适配器输入220v的电流
this.outPut220v();
//模拟转换的过程
System.out.println("开始转换220v的电流为12v....");
//模拟输出转好的电流
System.out.println("转换成功,输出转好的12v电流!!!...");
}
}
ps:类适配器,继承适配源类,并实现了适配目标接口。
继承适配源类,使它获得了生产220v电流的方法。
实现目标接口,是为了向外提供输出12v电流的方法。
类关系图:
ps:根据组合优于继承的原则,不推荐这种方式。
总结
当希望将一个类转换为满足另一个新接口的类时,可以使用类的适配器模式。
当希望将一个对象转换成满足另一个新接口的对象,可以使用对象的适配器模式。
具体怎么用,还是得实际情况分析。
其他
有的文章还有接口适配器,没有找到太多的资料,有机会再说
参考文献:
JAVA设计模式之适配器模式