適配器(Adapter)模式就是將一個類的接口轉換成客戶希望的另外一個接口。
適配器(Adapter)模式使得原本由於接口不兼容而不能一起工作的那些類可以在一起工作。
模式中的角色
- 目標接口(Target):客戶所期待的接口。目標可以是具體的或抽象的類,也可以是接口。
- 需要適配的類(Adaptee):需要適配的類或適配者類。
- 適配器(Adapter):通過包裝一個需要適配的對象,把原接口轉換成目標接口。
實現方式
- 類的適配器模式(採用繼承實現)
- 對象適配器(採用對象組合方式實現)
類適配器模式
// 已存在的、具有特殊功能、但不符合我們既有的標準接口的類
class Adaptee {
public void specificRequest() {
System.out.println("被適配類具有 特殊功能...");
}
}
// 目標接口,或稱爲標準接口
interface Target {
public void request();
}
// 具體目標類,只提供普通功能
class ConcreteTarget implements Target {
public void request() {
System.out.println("普通類 具有 普通功能...");
}
}
// 適配器類,繼承了被適配類,同時實現標準接口
class Adapter extends Adaptee implements Target{
public void request() {
super.specificRequest();
}
}
// 測試類public class Client {
public static void main(String[] args) {
// 使用普通功能類
Target concreteTarget = new ConcreteTarget();
concreteTarget.request();
// 使用特殊功能類,即適配類
Target adapter = new Adapter();
adapter.request();
}
}
對象適配器模式
// 適配器類,直接關聯被適配類,同時實現標準接口
class Adapter implements Target{
// 直接關聯被適配類
private Adaptee adaptee;
// 可以通過構造函數傳入具體需要適配的被適配類對象
public Adapter (Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
// 這裏是使用委託的方式完成特殊功能
this.adaptee.specificRequest();
}
}
// 測試類
public class Client {
public static void main(String[] args) {
// 使用普通功能類
Target concreteTarget = new ConcreteTarget();
concreteTarget.request();
// 使用特殊功能類,即適配類,
// 需要先創建一個被適配類的對象作爲參數
Target adapter = new Adapter(new Adaptee());
adapter.request();
}
}
優點
- 通過適配器,客戶端可以調用同一接口,因而對客戶端來說是透明的。這樣做更簡單、更直接、更緊湊。
- 複用了現存的類,解決了現存類和複用環境要求不一致的問題。
- 將目標類和適配者類解耦,通過引入一個適配器類重用現有的適配者類,而無需修改原有代碼。
- 一個對象適配器可以把多個不同的適配者類適配到同一個目標,也就是說,同一個適配器可以把適配者類和它的子類都適配到目標接口。
缺點
對於對象適配器來說,更換適配器的實現過程比較複雜。
適用場景
- 系統需要使用現有的類,而這些類的接口不符合系統的接口。
- 想要建立一個可以重用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作。
- 兩個類所做的事情相同或相似,但是具有不同接口的時候。
- 舊的系統開發的類已經實現了一些功能,但是客戶端卻只能以另外接口的形式訪問,但我們不希望手動更改原有類的時候。
- 使用第三方組件,組件接口定義和自己定義的不同,不希望修改自己的接口,但是要使用第三方組件接口的功能。