声明:
本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。
本博客已标明出处,如有侵权请告知,马上删除。
1. 适配器模式讲解
- 定义:将一个类的接口转换成客户期望的另一个接口
- 使原本接口不兼容的类可以一起工作
- 类型:结构型
- 适用场景
- 已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)
- 不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案
- 优点
- 能提高类的透明性和复用,现有的类复用但不需要改变
- 目标类和适配器类解耦,提高程序扩展性
- 符合开闭原则
- 缺点
- 适配器编写过程需要全面考虑,可能会增加系统的复杂性
- 增加系统代码可读的难度
- 拓展
- 对象适配器:符合合成复用原则,使用委托机制
- 类适配器:通过类继承来实现
- 相关设计模式
- 适配器模式和外观模式
- 适配器模式和外观模式都是对现有的类的封装
- 适配器模式是复用一个原有的接口,外观模式定义了新的接口
- 适配器模式是使两个原有的接口协同工作,外观模式则是在现有的系统中提供一个更为方便的访问入口
- 适配器模式和外观模式
2. 适配器模式 Coding
适配器模式分为对象适配器和类适配器,他们的区别在于对象适配器通过组合实现,类适配器通过继承实现,下面分别进行演示。
类适配器
-
创建一个被适配类
public class Adaptee { public void adapteeRequest() { System.out.println("被适配者的方法"); } }
-
创建目标方法的接口
public interface Target { void request(); }
-
创建接口实现类
public class ConcreteTarget implements Target { @Override public void request() { System.out.println("ConcreteTarget目标方法"); } }
-
创建适配器类,继承被适配类,实现目标方法接口
public class Adapter extends Adaptee implements Target { @Override public void request() { super.adapteeRequest(); } }
-
测试类
public class Test { public static void main(String[] args) { Target target = new ConcreteTarget(); target.request(); // 通过适配器实现 Target adapterTarget = new Adapter(); adapterTarget.request(); } }
运行结果:
ConcreteTarget目标方法 被适配者的方法
分析:当我们调用适配器类的目标方法时,实际调用的是被适配类中的方法。
现在类图如下所示:
对象适配器
还是上面的业务场景,使用对象适配器只需要修改适配器类。
适配器类不再继承被适配类,而是将被适配类作为属性组合到适配器中,然后通过对象来调用被适配类里面的方法
public class Adapter implements Target {
private Adaptee adaptee = new Adaptee();
@Override
public void request() {
adaptee.adapteeRequest();
}
}
现在类图如下所示:
下面我们再类引入一个生活场景:手机充电器的适配器,将 220V 的交流电转换成 5V 的直流电。
-
创建被适配的类,220V 的交流电类
public class AC220 { public int outputAC220V() { int output = 220; System.out.println("输出220V的交流电"+output+"V"); return output; } }
-
创建目标方法的接口,5V 的直流电类
public interface DC5 { int outputDC5V(); }
-
创建适配器类
public class PowerAdapter implements DC5 { private AC220 ac220 = new AC220(); @Override public int outputDC5V() { int adapterInput = ac220.outputAC220V(); /** 变压器 */ int adapterOutput = adapterInput / 44; System.out.println("通过PowerAdapter电源适配器输入AC"+adapterInput+"V"+"输出DC:"+adapterOutput+"V"); return adapterOutput; } }
-
测试类
public class Test { public static void main(String[]args){ DC5 dc5 = new PowerAdapter(); dc5.outputDC5V(); } }
运行结果:
输出220V的交流电220V 通过PowerAdapter电源适配器输入AC220V输出DC:5V