適配器模式的定義:將一個類的介面,轉換成客戶期望的另一個介面。適配器讓原本介面不相容的類可以合作無間。 適配器模式其實也可以叫做轉換器模式,由定義可知適配器其實就是包裝某些對象從而讓他們的幾口開起來不像自己而像是別的東西。舉一個簡單的例子 : 假設現在已有一個軟體系統,你希望它能和一個新的廠...
適配器模式的定義:將一個類的介面,轉換成客戶期望的另一個介面。適配器讓原本介面不相容的類可以合作無間。
適配器模式其實也可以叫做轉換器模式,由定義可知適配器其實就是包裝某些對象從而讓他們的幾口開起來不像自己而像是別的東西。舉一個簡單的例子 :
假設現在已有一個軟體系統,你希望它能和一個新的廠商類庫搭配使用,但是這個新廠商所設計出來的介面不同於舊廠商的介面,如下圖所示:
此時如果不想改變現有代碼解決這個問題,就可以重新寫一個類,這個類負責將新廠商介面轉接成你所期望的介面,這個類就是一個適配器:
這個適配器實現了你的類所期望的介面,而且這個適配器也能和廠商的介面溝通,這個適配器工作起來就如同一個中間人,它將客戶所發出的請求轉換成廠商類能理解的請求,這就是適配器模式。
再通過代碼的例子來詳細瞭解一下這個模式,現在有一個鴨子和火雞的介面聲明如下:
public interface Duck {
public void quack();
public void fly_long();
}
public interface Turkey {
public void gobble();
public void fly_short();
}
實現一個具體的鴨子和火雞類
public class MallardDuck implements Duck { @Override public void quack() { // TODO Auto-generated method stub System.out.println("Quack!"); } @Override public void fly_long() { // TODO Auto-generated method stub System.out.println("I'm flying!"); } }
public class WildTurkey implements Turkey { @Override public void gobble() { // TODO Auto-generated method stub System.out.println("Gobble!"); } @Override public void fly_short() { // TODO Auto-generated method stub System.out.println("I'm flying a short distance"); } }
現在假設你缺少鴨子對象,想用一些火雞對象來冒充,顯而易見因為火雞的介面不同,所以不能直接拿來用,所以寫個適配器類完成這個轉化過程:
public class TurkeyAdapter implements Duck { Turkey turkey; public TurkeyAdapter(Turkey turkey) { this.turkey = turkey; } @Override public void quack() { // TODO Auto-generated method stub turkey.gobble(); } @Override public void fly_long() { // TODO Auto-generated method stub for (int i = 0; i < 5; i++) {//變成能夠長距離飛行 turkey.fly_short(); } } }
測試一下:
public class DuckTestDriver { public static void main(String[] args) { // TODO Auto-generated method stub MallardDuck duck = new MallardDuck(); WildTurkey turkey = new WildTurkey(); Duck turkeyAdapter = new TurkeyAdapter(turkey); System.out.println("The Turkey says..."); turkey.gobble(); turkey.fly_short(); System.out.println("\nThe Duck says..."); testDuck(duck); System.out.println("\nThe TurkeyAdapter says..."); testDuck(turkeyAdapter);//這裡的鴨子其實是一個火雞冒充的 } static void testDuck(Duck duck) { duck.quack(); duck.fly_long(); } }
列印結果:
The Turkey says... Gobble! I'm flying a short distance The Duck says... Quack! I'm flying! The TurkeyAdapter says... Gobble! I'm flying a short distance I'm flying a short distance I'm flying a short distance I'm flying a short distance I'm flying a short distance
總之:
(1)當需要使用一個現有的類而其介面並不符合你的需要時,就使用適配器,適配器改變介面以符合客戶的期望。
(2)實現一個適配器可能需要一番功夫,也可能不費功夫,視目標介面的大小與複雜度而定(為什麼這麼說是因為適配器並不是只能包裝一個類儘管上邊的例子確實只包裝了一個火雞類,可以通過適配器來適配許多類來提供一個介面讓客戶編碼)。