定义
将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 属于结构型设计模式
场景举例
/**
*
* 有这么一个场景 使用类适配器 实现 一个手机充电器
* 1. 有一个总电压的类 输出220V的电压
* 2. 有一个手机充电器要使用的电压接口 输出5V的电压
* 3. 要有一个适配器类 将220V 转换成5V
*/
类适配器
第一步: 创建一个输出220V电压的类
public class AV220 {
public int outputAC220V(){
int output = 220;
System.out.println("输出电压" + output + "V");
return output;
}
}
第二步: 创建一个输出5V的接口
public interface DC5V {
int output5V();
}
第三步:创建一个类适配器 从而实现220V到5V的转换
public class ClassPowerAdapter extends AV220 implements DC5V{
@Override
public int output5V() {
int ac220V = outputAC220V();
int ac5V = ac220V / 44;
System.out.println("输出电压" + ac5V + "V");
return ac5V;
}
}
客户端代码
ClassPowerAdapter classPowerAdapter = new ClassPowerAdapter();
classPowerAdapter.output5V();
分析:类适配器继承了适配接口以及目标类,但是客户端创建的类适配器中的方法还可以使用output220V ,违反了(最小知道原则)里氏替换原则。因此引出了对象适配器
对象适配器
对象适配器就是不再继承目标类AV220,而是将该类作为一个对象放进适配器中
public class ObjectPowerAdapter implements DC5V{
private AV220 av220;
public ObjectPowerAdapter(AV220 av220) {
this.av220 = av220;
}
@Override
public int output5V() {
int ac220V = av220.outputAC220V();
int dc5v = ac220V / 44;
System.out.println("输出电压" + dc5v + "V");
return dc5v;
}
}
客户端代码:
ObjectPowerAdapter objectPowerAdapter = new ObjectPowerAdapter(new AV220());
objectPowerAdapter.output5V();
分析:这样实现符合了里氏替换原则,但是如果我想要适配更多的电压接口,就需要不断的增加类,造成类比较冗余,因此引出了接口适配器
接口适配器
接口适配器就是提供一个通用的适配器,可以适配不同的电压转化
适配器接口
public interface DC {
int output5V();
int output22V();
int output20V();
}
适配器接口的实现
public class InterfacePowerAdapter implements DC{
private AV220 av220;
public InterfacePowerAdapter(AV220 av220) {
this.av220 = av220;
}
@Override
public int output5V() {
return convertToPower(44);
}
private int convertToPower(int divide) {
int ac220V = av220.outputAC220V();
int ac5V = ac220V / divide;
System.out.println("输出电压" + ac5V + "V");
return ac5V;
}
@Override
public int output22V() {
return convertToPower(10);
}
@Override
public int output20V() {
return convertToPower(11);
}
}
客户端代码
InterfacePowerAdapter interfacePowerAdapter = new InterfacePowerAdapter(new AV220());
interfacePowerAdapter.output20V();
分析: 接口适配器虽然实现了不同的接口适配,但同时它也违反了接口隔离原则和单一职责原则,因此,要根据具体情况来分析使用哪一种方式
优缺点
优点:
1.能提高类的透明性和复用,现有的类复用但不需要改变
2.目标类和适配器类解耦,提高程序的扩展性
3. 在很多业务场景中符合开闭原则
缺点:
1. 适配器编写过程需要全面考虑,可能会增加系统的复杂性
2.增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱