文章目錄
1. 插座問題
泰國的插座是兩口的, 中國是三口的, 去泰國怎麼使用充電器?
買個多功能轉換插頭(適配器) 就OK了
2. 基本介紹
- 適配器模式是將某個類的接口轉換成客戶端所期望的另一個接口表示, 主要目的是兼容性, 讓原本因爲接口不匹配不能在一起工作的兩個類可以協同工作. 其別名爲包裝器 (Wrapper)
- 適配器,模式屬於結構型模式
- 主要分成三類: 類適配器模式 對象適配器模式 接口適配器模式
3. 工作原理
- 適配器模式: 將一個類接口轉換成另一個接口, 讓原本接口不兼容的類可以兼容
- 從用戶的角度看不到被適配者, 是解耦的
- 用戶調用適配器轉化出來的目標接口方法, 適配器再調用被適配者的相關接口方法
- 用戶收到反饋結果, 感覺只是和目標接口交互, 如圖
4. 類適配器模式
4.1 基本介紹
Adapter類, 通過集成src類, 實現dst類接口, 完成src -> dst的適配
4.2 案例
以生活中充電器的例子來講解適配器,充電器本身相當於Adapter,220V交流電
相當於src (即被適配者),我們的目dst(即 目標)是5V直流電
package com.liyang;
// 1. 源電壓220V
public class Voltage220V {
public int outputVoltage() {
return 220;
}
}
package com.liyang;
// 2. 手機類, 只能使用5V的電壓
public class Phone {
public void charging(Voltage5V voltage5v) {
if (voltage5v.outputVoltage() == 5) {
System.out.println("正在以5V充電呢...");
} else {
System.out.println("電壓不對, 無法充電...");
}
}
}
package com.liyang;
// 3. 那麼我們在這裏做一個適配器接口, 對220V的電壓進行時適配
public interface Voltage5V {
public int outputVoltage();
}
package com.liyang;
public class VoltageAdapter extends Voltage220V implements Voltage5V {
@Override
public int outputVoltage() {
return super.outputVoltage()/44;
}
}
package com.liyang;
// 4. 使用下
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}
4.3 注意事項
- java的單繼承機制, 所以類適配器需要繼承src類算是一個缺點, 因爲這就要求dst必須是接口, 有一定的侷限性
- src類的方法在Adapter中都會暴露出來, 也增加了使用成本
- 由於其繼承了src類, 所以可以根據需求重寫src類的方法, 使得Adapter的靈活性增強
5. 對象適配器
5.1 介紹
- 基本思路相同, 只是Adapter類不繼承Src類, 而是持有src的實例, 以解決兼容性問題
- 根據 合成複用原則 , 儘量使用關聯來替代繼承
- 對象是配偶器是最常用的
5.2 案例
package com.liyang;
// 1. 源電壓220V
public class Voltage220V {
public int outputVoltage() {
return 220;
}
}
package com.liyang;
// 2. 手機類, 只能使用5V的電壓
public class Phone {
public void charging(Voltage5V voltage5v) {
if (voltage5v.outputVoltage() == 5) {
System.out.println("正在以5V充電呢...");
} else {
System.out.println("電壓不對, 無法充電...");
}
}
}
package com.liyang;
// 3. 那麼我們在這裏做一個適配器接口, 對220V的電壓進行時適配
public interface Voltage5V {
public int outputVoltage();
}
package com.liyang;
public class VoltageAdapter implements Voltage5V {
private Voltage220V voltage220v;
public void setVoltage220v(Voltage220V voltage220v) {
this.voltage220v = voltage220v;
}
@Override
public int outputVoltage() {
return voltage220v.outputVoltage()/44;
}
}
package com.liyang;
// 4. 使用下
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
VoltageAdapter voltageAdapter = new VoltageAdapter();
voltageAdapter.setVoltage220v(new Voltage220V());
phone.charging(voltageAdapter);
}
}
5.3 注意事項
- 使用組合代替繼承, 解決了類適配器必須繼承src的侷限性問題, 也不再要求dst必須是接口
- 成本更低 更靈活
6. 接口適配器
6.1 介紹
- 當不需要全部實現接口的方法, 可以先設計一個抽象類實現接口, 提供默認實現(空方法), 這樣該抽象類的子類就可以有選擇的重寫某些方法
- 使用於一個接口不想使用其所有方法的情況
- 又叫適配器模式 或者 缺省適配器模式