工作原理:
适配器模式属于结构型模式,主要分三类:类适配器模式、对象适配器模式、接口适配器模式
假设我们现在有这么一个需求:需要给我们的手机充电,手机充电只能使用5V的电压,但是我们家里的插座却是220V的电压,也就是说手机无法直接使用220V的插座进行充电,那么现在就需要一个适配器来进行5V电压和220V电压的转换,这个适配器就是我们平时所用的充电器。
类图:
代码实现:
//被适配的类
public class Voltage220V {
//输出 220V 的电压
public int output220V() {
int src = 220;
System.out.println("电压=" + src + "伏");
return src;
}
}
//适配接口
public interface IVoltage5V {
public int output5V();
}
//适配器类
public class VoltageAdapter extends Voltage220V implements IVoltage5V {
@Override
public int output5V() {
//获取到 220V 电压
int srcV = output220V();
int dstV = srcV / 44 ; //转成 5v
return dstV;
}
}
//手机类
public class Phone {
//充电
public void charging(IVoltage5V iVoltage5V) {
if(iVoltage5V.output5V() == 5) {
System.out.println("电压为 5V, 可以充电~~");
} else if (iVoltage5V.output5V() > 5) {
System.out.println("电压大于 5V, 不能充电~~");
}
}
}
//客户端
public class Client {
public static void main(String[] args) {
System.out.println(" === 类适配器模式 ====");
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}
通过上面的例子,我们再来理解一下适配器模式的工作原理,就非常清晰了;适配器模式的工作原理是说将一个类的接口转换成客户希望的另外一个接口,代入上面的例子中,也就是说把已存在的220V这个类转换成手机充电需要的5V接口了;另外,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作;即指的是由于手机不能直接与220V的电压一起工作,但是有了适配器之后,就使得手机可以与220V电压一起工作了(间接)
关于类适配器:
类图如下:
代码如下:
只提供适配器类的代码,其它代码可以参考类适配器模式
//适配器类
public class VoltageAdapter implements IVoltage5V {
//使用聚合
private Voltage220V voltage220V;
public VoltageAdapter(Voltage220V voltage220V){
this.voltage220V=voltage220V;
}
@Override
public int output5V() {
int dst = 0;
if(null != voltage220V) {
int src = voltage220V.output220V();//获取 220V 电压
System.out.println("使用对象适配器,进行适配~~");
dst = src / 44;
System.out.println("适配完成,输出的电压为=" + dst);
}
return dst;
}
}
关于对象适配器:
核心思路:当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求;适用于一个接口不想使用其所有的方法的情况。
为什么要使用适配器接口呢?试想,如果我们的目标接口中有多个方法需要进行适配,那么每一个适配器去实现这个目标接口的话都需要实现接口中的所有方法,但是这个适配器类只需要针对某一个方法进行适配,而每次都要实现所有方法,即使是空实现,也会使代码变得非常冗余,所以才需要适配器接口;让这个适配器接口去实现目标接口所有方法(空实现),而具体的适配器再去继承适配器接口,再针对需要的方法去重写即可!
类图如下:
代码如下:
//被适配的类
public class Voltage220V {
//输出 220V 的电压
public int output220V() {
int src = 220;
System.out.println("电压=" + src + "伏");
return src;
}
}
//目标接口:可能是5V、9V、12V、24V
public interface IVoltage {
int output5V();
int output9V();
int output12V();
int output24V();
}
//适配器抽象类,也可以直接说成是适配器接口,是一个万能适配器,可以实现多种电压的转换
//适配器接口是一个抽象类,实现了目标接口,并重写了目标接口的所有方法,只是这些方法都是空实现
//只需要让具体的适配器去继承这个适配器接口,并对需要的方法进行重写即可!
public abstract class abstractAdapter implements IVoltage{
@Override
public int output5V() {
return 0;
}
@Override
public int output9V() {
return 0;
}
@Override
public int output12V() {
return 0;
}
@Override
public int output24V() {
return 0;
}
}
//具体的适配器类:实现5V-220V的转换
public class Adapter extends abstractAdapter {
private Voltage220V voltage220V;
public Adapter(Voltage220V voltage220V) {
this.voltage220V=voltage220V;
}
@Override
public int output5V() {
int src = voltage220V.output220V();
int des=src/44;
return des;
}
}
//手机类
public class Phone {
//充电
public void charging(IVoltage iVoltage) {
if(iVoltage.output5V() == 5) {
System.out.println("电压为 5V, 可以充电~~");
} else if (iVoltage.output5V() > 5) {
System.out.println("电压大于 5V, 不能充电~~");
}
}
}
//客户端
public class Client {
public static void main(String[] args) {
System.out.println(" === 类适配器模式 ====");
Phone phone = new Phone();
phone.charging(new Adapter(new Voltage220V()));
}
}
关于适配器模式在SpringMVC中的应用可以参考另一篇博客:https://blog.csdn.net/can_chen/article/details/105524137