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