OO適配器是什麼,必定不難理解,由於現實中處處都是。比方說:若是你須要一個兩項插頭,但牆上只有一個三項插座,這時候你就須要使用一個交流電的適配器……java
又或者你須要對經過串口對某設備進行調試,可是你的機器沒有串口,只有USB接口,這時候你就須要一個USB轉串口的適配器……測試
這是真實世界的適配器,那面向對象適配器又是什麼?其實,OO適配器和真實世界的適配器扮演着一樣的角色:將一個接口轉換成另外一個接口,以符合客戶的指望。this
假設已有一個軟件系統,它與舊廠商的某個接口搭配使用。你但願替換掉舊廠商,讓它能和一個新廠商類庫搭配使用,可是這個新廠商所設計出來的接口,不一樣於舊廠商的接口。你不想改變現有的代碼解決這個問題。因此須要編寫一個適配器,這個適配器工做起來就如同一箇中間人,它將客戶所發出的請求轉換成新廠商能理解的請求。spa
以鴨子類爲例,鴨子能夠飛,而且能夠呱呱叫,如下是鴨子類的接口與實現:設計
public interface Duck { // 呱呱叫 public void quack(); // 飛 public void fly(); } public class MallardDuck implements Duck { public void quack() { System.out.println("Quack"); } public void fly() { System.out.println("I'm flying"); } }
接下來再看一個「街頭頑禽」火雞類的接口和實現類:調試
public interface Turkey { // 火雞不會呱呱叫,只會咯咯叫 public void gobble(); // 夥計會飛,雖然飛不遠 public void fly(); } public class WildTurkey implements Turkey { public void gobble() { System.out.println("Gobble gobble"); } public void fly() { System.out.println("I'm flying a short distance"); } }
如今,假設你缺鴨子對象,想用一些火雞對象冒充。顯而易見,由於火雞的接口不一樣,因此咱們不能公然拿來用。 因此就須要寫一個適配器。code
也就是說,加入你有一個方法,參數是Duck接口,你想把Turkey接口傳遞進去。對象
接下來適配器的代碼:接口
// 首先,適配器須要實現想轉換成的接口類型。 // 這裏想把火雞轉換成鴨子,因此實現了鴨子的接口。 public class TurkeyAdapter implements Duck { Turkey turkey; // 接着,須要取得要適配的對象引用。 // 也就是你的客戶所指望看到的接口。 // 這裏想把火雞轉換成鴨子,因此傳入火雞的接口。 public TurkeyAdapter(Turkey turkey) { this.turkey = turkey; } // 在鴨子叫的方法中調用火雞叫的方法。 public void quack() { turkey.gobble(); } // 在鴨子飛的方法中調用火雞飛的方法。 // 由於火雞飛不遠,鴨子飛一次,火雞須要飛五次。 public void fly() { for (int i = 0; i < 5; i++) { turkey.fly(); } } }
測試適配器:get
public class Client { public static void main(String[] args) { // 建立一隻鴨子 MallardDuck duck = new MallardDuck(); // 建立一直火雞 WildTurkey turkey = new WildTurkey(); // 將火雞包裝進一個火雞適配器,是它看起來像是一隻鴨子。 Duck turkeyAdapter = new TurkeyAdapter(turkey); System.out.println("The Turkey says..."); turkey.gobble(); turkey.fly(); 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(); } }
首先讓火雞又叫又飛,接着讓鴨子又叫又飛,最後讓適配器處理過的火雞像鴨子同樣又叫又飛,quack()被調用時,適配器咯咯叫。testDuck()方法根本不知道,這實際上是一隻僞裝成鴨子的火雞!
如今咱們已經知道什麼是適配器了,讓咱們退後一步,再次看看各部分之間的關係。‘
客戶端調用適配器的過程以下:
如今來看看適配器模式的類圖:
這個適配器模式充滿良好的OO設計原則:使用對象組合,以修改的接口包裝被適配者,這種作法還有額外的優勢,那就是,被適配者的任何子類,均可以搭配着適配器使用。
在上面的類圖中,鴨子類就是Target類,火雞類就是Adaptee類。
以上就是適配器模式。