適配器模式
適配器模式(Adapter),將一個類的接口轉換成客戶希望的另外一個藉口。適配器模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。它主要應用於希望複用一些現存的類,但是接口又於複用環境要求不一致的情況。
適配器模式主要分爲三類:對象適配器模式、類適配器模式、接口適配器模式。
適配器模式解析
這裏主要以對象適配器爲例。
角色介紹
- Target:客戶所期待的接口,可以是具體的或抽象的類,也可以是接口。
- Adaptee:需要適配的類。
- Adapter:通過在內部包裝一個 Adaptee 對象,把源接口轉換成目標接口。
適配器模式基本代碼
- Target 類:目標類。
public class Target {
public void request() {
System.out.println("普通請求!");
}
}
- Adaptee 類:需要適配的類。
public class Adaptee {
public void specificRequest() {
System.out.println("特殊請求!");
}
}
- Adapter 類:適配器類。
public class Adapter extends Target {
private Adaptee adaptee = new Adaptee();
@Override
public void request() {
adaptee.specificRequest();
}
}
- Main 類
public class Main {
public static void main(String[] args) {
Target target = new Adapter();
target.request();
}
}
示例
以充電器爲例,充電器本身相當於 Adapter, 220V 交流電相當於被適配者 Adaptee,轉換爲 5V 直流電相當於目標者。
對象適配器
/**
* Voltage220V
*/
public class Voltage220V {
public int output220V() {
return 220;
}
}
/**
* Voltage5V
*/
public interface Voltage5V {
int output5V();
}
/**
* VoltageAdapter
*/
public class VoltageAdapter implements Voltage5V {
private Voltage220V voltage220V = new Voltage220V();
@Override
public int output5V() {
int output220V = voltage220V.output220V();
return output220V / 44;
}
}
/**
* Main
*/
public class Main {
public static void main(String[] args) {
Voltage5V voltage5V = new VoltageAdapter();
System.out.println(voltage5V.output5V());
}
}
對象適配器,遵循合成複用原則,使用成本低,並且靈活。
類適配器
/**
* Voltage220V
*/
public class Voltage220V {
public int output220V() {
return 220;
}
}
/**
* Voltage5V
*/
public interface Voltage5V {
int output5V();
}
/**
* VoltageAdapter
*/
public class VoltageAdapter extends Voltage220V implements Voltage5V {
@Override
public int output5V() {
int output220V = this.output220V();
return output220V / 44;
}
}
/**
* Main
*/
public class Main {
public static void main(String[] args) {
Voltage5V voltage5V = new VoltageAdapter();
System.out.println(voltage5V.output5V());
}
}
由於 Java 是單繼承機制,所以類適配器需要繼承被適配類,有一定侷限性;被適配類的方法在 Adapter 中都會暴露出來,也增加了使用的成本。但是其繼承了被適配類,所以它可以根據需求重寫被適配類中的方法,使得Adapter 的靈活性增強了。
接口適配器
當不需要全部實現接口提供的方法時,可先設計一個抽象類實現接口,併爲該接口中每個方法提供一個默認實現(空方法),那麼該抽象類的子類可有選擇地覆蓋父類的某些方法來實現需求。適用於一個接口不想使用其所有的方法的情況。
/**
* Voltage
*/
public interface Voltage {
int output5V();
int output10V();
int output20V();
}
/**
* AbstractVoltage
*/
public abstract class AbstractVoltage implements Voltage {
@Override
public int output5V() {
return 0;
}
@Override
public int output10V() {
return 0;
}
@Override
public int output20V() {
return 0;
}
}
/**
* Voltage220V
*/
public class Voltage220V {
public int output220V() {
return 220;
}
}
/**
* Voltage5V
*/
public class Voltage5V extends AbstractVoltage {
private Voltage220V voltage220V = new Voltage220V();
@Override
public int output5V() {
int v = voltage220V.output220V();
return v / 44;
}
}
/**
* Main
*/
public class Main {
public static void main(String[] args) {
Voltage5V voltage5V = new Voltage5V();
System.out.println(voltage5V.output5V());
}
}
小結
一般地,使用一個已經存在的類,但如果它的接口,也就是它的方法和要求不相同時,就可以考慮使用適配器模式。