java设计模式——适配器模式(电压适配问题)

    技术2025-09-06  50

    1、引入需求背景

    生活中手机充电需要的是5V 直流电,而电压是20V 交流电。所以中间我们需要一个充电器将220V -> 5V。

    引申一下,充电器本身相当于 Adapter,220V 交流电相当于 src (即被适配者),我们 的目 dst(即 目标)是 5V 直流电。

    2、适配器模式的三种模式

    类适配器模式对象适配器模式接口适配器模式

    接下来我们通过三种模式来实现上述的需求。

    2.1 类适配器模式

    2.1.1 类图分析

    分析:有一个提供220V电压的Voltage220V类,以及输出5V电压的接口,再来一个VoltageAdapter类去分别的继承和实现,而Phone的方法只要去依赖接口就可以了。

    2.1.2 代码实现
    public class Voltage220V { public int output() { return 220; } } public interface IVoltage5V { int output(); } public class VoltageAdapter extends Voltage220V implements IVoltage5V { @Override public int output() { int output = super.output(); System.out.println("输出"+output); System.out.println("转换一下让他变成5"); return 5; } } public class Phone { public void charging(IVoltage5V iVoltage5V) { System.out.println(iVoltage5V.output()+"V充电"); } } public class Client { public static void main(String[] args) { Phone phone = new Phone(); phone.charging(new VoltageAdapter()); } }
    2.1.3 总结
    Java 是单继承机制,所以类适配器需要继承 src 类这一点算是一个缺点, 因为这要求 dst 必须是接口,有一定局限性;src 类的方法在 Adapter 中都会暴露出来,也增加了使用的成本。由于其继承了src类,所以它可以根据需求重写src类的方法,使得Adapter的灵活性增强了。

    2.2 对象适配器模式

    2.2.1 类图分析

    分析:对象适配器模式的思路和类适配器模式基本上保持一致,不同在于对象适配器模式不是在继承Voltage220V,而是采用聚合的方式,引入这个对象,降低耦合。

    2.2.2 代码实现

    大致代码和上述模式基本上保持一致,就是去掉继承,改成组合。

    public class VoltageAdapter implements IVoltage5V { private Voltage220V voltage220V; public VoltageAdapter(Voltage220V voltage220V) { this.voltage220V = voltage220V; } @Override public int output() { int output = voltage220V.output(); System.out.println("输出"+output); System.out.println("转换一下让他变成5"); return 5; } } public class Client { public static void main(String[] args) { Phone phone = new Phone(); phone.charging(new VoltageAdapter(new Voltage220V())); } }
    2.2.3 总结
    对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。 根据合成复用原则,使用组合替代继承, 所以它解决了类适配器必须继承 src 的局限性问题,也不再要求 dst 必须是接口。使用成本更低,更灵活。

    2.3 接口适配器模式

    当接口里方法很多,而不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。

    2.3.1 代码实现
    public interface IVoltageAdapter { void m1(); void m2(); void m3(); void m4(); } public abstract class AbstractVoltage implements IVoltageAdapter{ @Override public void m1() { } @Override public void m2() { } @Override public void m3() { } @Override public void m4() { } }

    我们用到接口里的哪个方法就去覆盖某一个方法。

    public class Phone { public void charging() { //只需要去覆盖我们需要使用的接口方法 IVoltageAdapter adapter = new AbstractVoltage(){ @Override public void m1() { super.m1(); } }; adapter.m1(); } public static void main(String[] args) { Phone phone = new Phone(); phone.charging(); } }
    Processed: 0.021, SQL: 9