概念
適配器模式是指將一個接口轉換爲客戶希望的另外一個接口,該模式使得原本不兼容的類可以一起工作。實現了由“源”到“目標”的適配,適配器負責把“源”過度到“目標”。
模式結構
例如Apple手機Android手機的充電器接口不兼容,在專賣店購買蘋果手機時一般都會帶一個充電器轉換頭,一個小小的插頭,鏈接在安卓手機充電器端就可以爲蘋果手機充電。這裏包含幾種設備也就是對應適配器模式結構中的幾種桔角色。
- 源角色(Adeptee 安卓手機充電器):需要被適配的接口
- 目標抽象角色(Target 蘋果充電器接口):客戶所期待要使用的接口
- 適配器(Adepter 轉換器):將安卓手機充電器接口轉換爲蘋果手機充電器接口,即把源接口轉換成符合要求的目標接口(即可以爲蘋果充電還保留了給安卓充電的功能)
- 客戶端(Client 蘋果手機):使用目標角色的設備
兩種適配器模式
類適配器模式
這種適配器模式就是主要用於單一的爲某個類而實現適配器的一種模式。
示例代碼
/**
* 客戶端
*/
public class AdpterClient {
public static void main(String[] args){
AppleCharger target = new Adapter();
target.chargeForApple();
target.chargeForAndroid();
}
}
/**
* 源-Adaptee
*/
class AndroidCharger{
public void chargeForAndroid(){
System.out.println("爲Android手機充電");
}
}
/**
* 目標-Target
*/
interface AppleCharger{
void chargeForAndroid();
void chargeForApple();
}
/**
* 適配器-Adapter
*/
class Adapter extends AndroidCharger implements AppleCharger{
@Override
public void chargeForApple() {
System.out.println("爲Apple手機充電");
}
}
輸出結果:
爲Apple手機充電
爲Android手機充電
也許會有人問爲什麼不直接在“源”中添加方法?其實適配器是爲了實現某種目的而爲源類暫時性的添加某種功能方法,所以不能直接改變原結構。再說,這也不符合Java高內聚低耦合的要求。適配器Adapter類繼承了AndroidCharder類,Java屬於單繼承語言,所以Adapter不能再繼承其他類了,這樣適配器就只爲AndroidCharger這一個類服務,所以稱爲類適配器。
對象適配器模式
對象適配器是把“源”作爲一個對象聚合到適配器類中。
例如上例中適配器代碼如下
class Adapter1 implements AppleCharger{
AndroidCharger androidCharger = new AndroidCharger();
public Adapter1(AndroidCharger androidCharger) {
this.androidCharger = androidCharger;
}
@Override
public void chargeForAndroid() {
androidCharger.chargeForAndroid();
}
@Override
public void chargeForApple() {//新增方法
System.out.println("爲Apple手機充電");
}
//如果技術能實現我還以爲電腦充電,即實現了爲多個源進行適配的功能
}
客戶端改爲
public class AdpterClient {
public static void main(String[] args){
AppleCharger target = new Adapter1(new AndroidCharger());
target.chargeForApple();
target.chargeForAndroid();
}
}
運行結果:同上
兩種適配器模式總結
- 類的適配器用於單一源的適配,源的單一化決定代碼實現不用寫邏輯選擇,結構清晰
- 對象適配器可以用於多源的適配,彌補了類適配器的不足,但同時增加了實現代碼的邏輯選擇複雜度,結構不太清晰
- 默認適配器我們想實現一個接口,但不想實現接口的所有方法,只想實現部分時用默認適配器,在接口和具體實現類之間添加一個抽象類,用抽象類去實現目標接口的所有方法,而具體的實現類繼承抽象類,只需要覆蓋其需要完成的部分方法即可。
默認適配器示例
interface Code{
void codeJava();
void codeC();
void codePhp();
}
abstract class CodeDefault implements Code{
public void codeC() {
}
public void codeJava() {
}
public void codePhp() {
}
}
class CodeImpl extends CodeDefault{
@Override
public void codeJava() {
System.out.println("我只會用Java語言寫代碼");
}
}