一、适配器模式定义
1.适配器模式又叫做变压器模式,它的功能是将一个类的接口变成客户端所期望的另一种接口,从而使原本因接口不匹配而导致无法在一起工作的两个类能够一起工作,属于结构型设计模式
2.在软件开发中,基本上任何问题都可以通过增加一个中间层进行解决。适配器模式,其实就是一个中间层。适配器模式其实起着转化/委托的作用,将一种接口转化为另一种符合需求的接口
3.适配器模式适用的场景:
A.已经存在的类,它的方法和需求不匹配(方法结果相同或相似)的情况
B.适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案。有点亡羊补牢的感觉
二、适配器模式示例
1.适配器模式一般包含三种角色:
A.目标角色(target):也就是我们期望的接口
B.源角色(Adaptee):存在于系统中,内容满足客户需求(需转换),但接口不匹配的接口实例
C.适配器(Adapter):将源角色转化为目标角色的类实例
2.适配器模式有3种形式:类适配器、对象适配器、接口适配器
3.类适配器
A.类适配器的原理就是通过继承来实现适配器功能。具体做法:让Adapter实现Target接口,并且继承Adaptee,这样Adapter就具备Target和Adaptee的特性,就可以将两者进行转化
B.代码示例
1 public class AC220 { 2 public int outputAC220V(){ 3 int output = 220; 4 System.out.println("输出电压" + output + "V"); 5 return output; 6 } 7 } 8 9 public interface DC5 { 10 int outputDC5V(); 11 } 12 13 public class PowerAdapter extends AC220 implements DC5 { 14 @Override 15 public int outputDC5V() { 16 int adapterInput = super.outputAC220V(); 17 int adapterOutput = adapterInput / 44; 18 System.out.println("使用Adapter输入AC" + adapterInput + "V,输出DC" + adapterOutput + "V"); 19 return adapterOutput; 20 } 21 } 22 23 public class ClassAdapterTest { 24 public static void main(String[] args) { 25 DC5 adapter = new PowerAdapter(); 26 adapter.outputDC5V(); 27 } 28 29 }
4.对象适配器
A.对象适配器的原理就是通过组合来实现适配器功能。具体做法:让Adapter实现Target接口,然后内部持有Adaptee实例,然后在target接口规定的方法内转换Adaptee
B.代码示例
1 public class PowerAdapter implements DC5 { 2 3 private AC220 ac220; 4 5 public PowerAdapter(AC220 ac220){ 6 this.ac220 = ac220; 7 } 8 9 @Override 10 public int outputDC5V() { 11 int adapterInput = ac220.outputAC220V(); 12 int adapterOutput = adapterInput / 44; 13 System.out.println("使用Adapter输入AC" + adapterInput + "V,输出DC" + adapterOutput + "V"); 14 return adapterOutput; 15 } 16 }
5.接口适配器
A.接口适配器的关注点与类适配器和对象适配器的关注点不太一样,类适配器和对象适配器着重于将系统存在的一个角色(Adaptee)转化成目标接口(Target)所需内容,而接口适配器的使用场景是解决接口方法过多,如果直接实现接口,那么类会多出许多空实现的方法,类显得很臃肿。此时,使用接口适配器就能让我们只实现我们需要的接口方法,目标更清晰
B.接口适配器的主要原理就是利用抽象类实现接口,并且空实现接口众多方法。
C.代码示例
1 public interface DC { 2 int output5V(); 3 int output12V(); 4 int output24V(); 5 int output36V(); 6 } 7 8 public class AC220 { 9 public int outputAC220V(){ 10 int output = 220; 11 System.out.println("输出电压" + 220 + "V"); 12 return output; 13 } 14 } 15 16 public class PowerAdapter implements DC { 17 18 private AC220 ac220; 19 20 public PowerAdapter(AC220 ac220){ 21 this.ac220 = ac220; 22 } 23 24 @Override 25 public int output5V() { 26 int adapterInput = ac220.outputAC220V(); 27 int adapterOutput = adapterInput / 44; 28 System.out.println("使用Adapter输入AC" + adapterInput + "V,输出DC" + adapterOutput + "V"); 29 return adapterOutput; 30 } 31 32 @Override 33 public int output12V() { 34 return 0; 35 } 36 37 @Override 38 public int output24V() { 39 return 0; 40 } 41 42 @Override 43 public int output36V() { 44 return 0; 45 } 46 } 47 48 public class InterfaceAdapterTest { 49 public static void main(String[] args) { 50 DC adapter = new PowerAdapter(new AC220()); 51 adapter.output5V(); 52 } 53 }
6.适配器模式和装饰器模式的对比
A.装饰器和适配器模式都是包装模式,装饰器也是一种特殊的代理模式
B.
装饰器模式 | 适配器模式 | |
形式 | 是一种非常特别的适配器模式 | 没有层级关系,装饰器模式有层级关系 |
定义 | 装饰器和被装饰器都实现同一个接口,主要目的是为了扩展之后依旧保留OOP关系 | 适配器和被适配者没有必然的联系,通常是采用继承或代理的形式进行包装 |
关系 | 满足is-a的关系 | 满足has-a的关系 |
功能 | 注重覆盖、扩展 | 注重兼容、转换 |
设计 | 前置考虑 | 后置考虑 |
7.适配器模式的优缺点
A.优点
a.能提高类的透明性和复用,现有的类复用但不需要改变
b.目标类和适配器类解耦,提高程序的扩展性
c.在很多业务场景中符合开闭原则
B.缺点
a.适配器编写过程需要全面考虑,可能会增加系统的复杂性
b.增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱