java適配器(Adapter)
1. 概念
適配器模式把一個類的接口轉換成客戶端期待的另外一種接口, 從而是原本應用接口不匹配而無法在一起工作的兩個類能夠在一起工作.
舉個例子來說,現在一般的家用電器要求的電壓都是 220V,但有個別電器要求使用110V 電壓,怎么辦?這時就需要用一個能把 220V 電壓轉換成 110V 電壓的變壓器,這個變壓器就是一個適配器。
2. 哪些情況需要適配器模式?
- 系統需要使用類的接口不符合系統的要求
- 要建立一個可以重復使用的類, 用於與該類之間的關聯不大的一些類, 包括工作中引用的類
- 類的適配器模式使用起來有點像多重集成機制, 利用接口的特性, 把一些零散類組織到一起, 成為一個新的類來實現調用, 並且看起來像是對一個類的操作. 實際上, 適配器模式更過的是強調對代碼的組織, 而不是功能的實
3. 適配器的作用
適配器模式可以方便代碼的主治和模型的准確標識, 可以把一個類中的成員插入到另一個類的繼承子類中, 從而上這個繼承的子類看起來像一個新類, 同事可以對父類減少依賴.
4. 適配器的角色
Target: 目標接口類, 客戶所期待的接口, 目標可以是具體的或者抽象的類, 也可以是接口
Adaptee: 需要適配的類
Adapter: 通過包裝一個需要的支配器對象, 把原來的接口轉換成目標接口
5. 適配器的實現方式
1. 對象適配器模式(采用對象組合方式實現)

代碼:
// 目標接口, 具有標准的接口
public interface Target {
public void request();
}
//已經存在的, 並且具有特殊功能的類, 但是不符合我們既有的標准的接口的類
public class Adaptee {
public void specificRequest() {
System.out.println("被適配類, 我是兩孔插座, 具有特殊的功能");
}
}
// 裝飾類, 直接關聯被適配器類, 同時實現標准接口
public class Adapter implements Target {
private Adaptee adaptee;
// 通過構造函數傳入被適配類對象
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
System.out.println("我是適配器類, 我能適配任何兩孔插座, 讓它正常工作");
// 這里使用委托的方式完成特殊的功能
this.adaptee.specificRequest();
}
}
public class App
{
public static void main( String[] args ) {
// 使用特殊功能類, 即適配類
// 需要先創建一個唄適配類的對象作為參數
Target target = new Adapter(new Adaptee());
target.request();
}
}
2. 類的適配器模式(采用繼承實現)

代碼:
//目標接口,或稱為標准接口
public interface Target {
//普通功能
public void request();
}
//已存在的、具有特殊功能、但不符合我們既有的標准接口的類
public class Adaptee {
public void specificRequest() {
System.out.println("被適配類...我是兩孔插座 具有特殊功能");
}
}
//適配器類,直接關聯被適配類,同時實現標准接口
class Adapter implements Target {
// 直接關聯被適配類
private Adaptee adaptee;
// 可以通過構造函數傳入具體需要適配的被適配類對象
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
}
public void request() {
// 這里是使用委托的方式完成特殊功能
System.out.println("我是適配器類 我能適配任何兩孔插座 讓它正常工作");
this.adaptee.specificRequest();
}
}
從類圖中我們也知道需要修改的只不過就是 Adapter 類的內部結構,即 Adapter 自身必須先擁有一個被適配類的對象,再把具體的特殊功能委托給這個對象來實現。使用對象適配器模式,可以使得 Adapter 類(適配類)根據傳入的 Adaptee 對象達到適配多個不同被適配類的功能,當然,此時我們可以為多個被適配類提取出一個接口或抽象類。這樣看起來的話,似乎對象適配器模式更加靈活一點
6. 類適配器和對象適配器的權衡
● 類適配器使用對象繼承的方式,是靜態的定義方式;而對象適配器使用對象組合的方式,是動態組合的方式。
對於對象適配器,一個適配器可以把多種不同的源適配到同一個目標。換言之,同一個適配器可以把源類和它的子類都適配到目標接口。因為對象適配器采用的是對象組合的關系,只要對象類型正確,是不是子類都無所謂。
● 對於對象適配器,要重定義Adaptee的行為比較困難,這種情況下,需要定義Adaptee的子類來實現重定義,然后讓適配器組合子類。雖然重定義 Adaptee的行為比較困難,但是想要增加一些新的行為則方便的很,而且新增加的行為可同時適用於所有的源。
● 對於類適配器,僅僅引入了一個對象,並不需要額外的引用來間接得到Adaptee。
● 對於對象適配器,需要額外的引用來間接得到Adaptee。
建議盡量使用對象適配器的實現方式,多用合成/聚合、少用繼承。當然,具體問題具體分析,根據需要來選用實現方式,最適合的才是最好的。
7. 適配器的優點
更好的復用性
系統需要使用現有的類,而此類的接口不符合系統的需要。那么通過適配器模式就可以讓這些功能得到更好的復用。
更好的擴展性
在實現適配器功能的時候,可以調用自己開發的功能,從而自然地擴展系統的功能。
8. 適配器的缺點
過多的使用適配器,會讓系統非常零亂,不易整體進行把握。比如,明明看到調用的是A接口,其實內部被適配成了B接口的實現,一個系統如果太多出現這種情況,無異於一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統進行重構。
