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

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 总结
  1. Java 是单继承机制,所以类适配器需要继承 src 类这一点算是一个缺点, 因为这要求 dst 必须是接口,有一定局限性;
  2. src 类的方法在 Adapter 中都会暴露出来,也增加了使用的成本。
  3. 由于其继承了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 总结
  1. 对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。 根据合成复用原则,使用组合替代继承, 所以它解决了类适配器必须继承 src 的局限性问题,也不再要求 dst 必须是接口。
  2. 使用成本更低,更灵活。

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();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章