你眼中的適配器是什麼樣子的呢?在設計模式中也有模式叫適配器模式,一塊兒來看看吧。
適配器是什麼這不須要做者我多解釋把,打個比方,在國內用的是220V的電器,但國外有些國家是110V甚至240V的也有等等,國內的充電線就不能直接插國外的插座了,這時候就須要一個適配器作電源轉換,是的,在設計模式中也有這麼一個模式與其相似,也是個頗有用的模式。編程
下面我作了幾個配圖來理解設計模式。設計模式
假設已有一個系統,此時它須要更新,你但願它能和新的廠商類庫搭配使用,可是這個新廠商設計出來的接口,與原系統的接口不同。因此二者不能直接匹配。ide
若重構原來的代碼可能會很是麻煩,並且又不能去改變廠商的代碼,怎麼辦呢?這是你能夠寫一個類,將新廠商接口轉換爲你所期待的接口。測試
那麼這個適配器就比如一箇中間人,它將客戶所發送的請求轉換成廠商類可以理解的請求。this
直接放一個例子,假如一隻火雞想要「冒充」成鴨子怎麼作呢?
代碼以下:spa
這是鴨子接口設計
package duck_Interface; /** * 適配器模式:就比如在中國的電器若要在美國的插座上使用,就必須使用適配器, * 適配器就至關於一箇中間層,將兩個本來不能相互溝通的東西鏈接在一塊兒 * * @author Joy * */ public interface Duck { public void quack(); public void fly(); }
綠頭鴨是鴨子的子類code
package duck_Implements; import duck_Interface.Duck; public class MallardDuck implements Duck { /** * 綠頭鴨 */ @Override public void quack() { System.out.println("綠頭鴨叫:呱呱呱"); } @Override public void fly() { System.out.println("我在飛"); } }
這是一隻火雞(接口)對象
package duck_Interface; /** * 火雞接口 * * @author Joy * */ public interface Turkey { // 火雞隻會咯咯咯叫 public void gobble(); // 火雞會飛,但飛不遠 public void fly(); }
這是火雞的一個具體實現繼承
package duck_Implements; import duck_Interface.Turkey; public class WildTurkey implements Turkey { /** * 火雞類的實現 */ @Override public void gobble() { System.out.println("火雞叫:咯咯咯"); } @Override public void fly() { System.out.println("我會飛,但飛不高"); } }
很顯然二者一開始不能直接匹配,這裏寫一個火雞適配器
package Adapter; import duck_Interface.Duck; import duck_Interface.Turkey; /** * 火雞的適配器 * * @author Joy * */ // 先要實現想要轉換的類型接口,(火雞但願和綠頭鴨交流) // 火雞:被適配者,鴨子:適配者 // 這裏火雞要實現鴨子接口 public class TurkeyAdapter implements Duck { Turkey turkey; // 須要取得適配的對象引用 // 利用構造器取得這個引用 public TurkeyAdapter(Turkey turkey) { this.turkey = turkey; } @Override public void quack() { // 如今咱們須要實現火雞裏的叫的方法 // 很簡單隻需直接引用 turkey.gobble(); } /** * 這裏因爲火雞的飛行距離短,鴨子飛行距離長, 爲二者飛行可以對應, 這裏得屢次調用火雞飛行方法,至關於火雞5次飛行的距離等於一次鴨子飛行的距離。。 */ @Override public void fly() { for (int i = 0; i < 5; i++) { turkey.fly(); } } }
測試類
package TestMain; import Adapter.TurkeyAdapter; import duck_Implements.MallardDuck; import duck_Implements.WildTurkey; import duck_Interface.Duck; public class DuckTestDrive { // 取得一隻鴨子 public static void testDuck(Duck duck) { duck.quack(); duck.fly(); } public static void main(String[] args) { // 建立好一隻鴨子和火雞 MallardDuck duck = new MallardDuck(); WildTurkey turkey = new WildTurkey(); // 而後將火雞「包裝」進火雞適配器中,讓它看上起像只鴨子 Duck turkeyAdapter = new TurkeyAdapter(turkey); System.out.println("這隻火雞說~~~~~"); turkey.gobble(); turkey.fly(); System.out.println("\n這隻鴨子說a~~~~~"); testDuck(duck); // 試着傳入一個僞裝是鴨子的火雞對象 System.out.println("\n火雞適配器說~~~~~"); /** * testDuck()方法不知道這是一隻僞裝鴨子的火雞 turkey調用叫的方法是「咯咯咯」 * 而fly方法調用了5次,就爲了讓火雞僞裝成鴨子同樣飛的遠 */ testDuck(turkeyAdapter); } }
效果圖
TurkeyAdapter裏的quack方法被調用,適配器咯咯咯的叫,而後fly方法被調用,適配器執行了5次飛行操做,而在testDuck(Duck duck)它還覺得參數duck真的是一鴨子,實際上是隻僞裝鴨子的火雞(turkeyAdapter)。
讓咱們再看看各部分之間的關係。
客戶使用適配器的過程以下:
一、客戶經過目標接口調用適配器的方法對適配器發出請求。
二、適配器(鴨子)使用被適配器(火雞)接口把請求轉換成被適配器的一個或多個調用接口。
三、客戶接收到調用的結果,但並未察覺這一切是適配器再起轉換做用。
定義適配器模式:將一個類的接口,轉換成客戶期待的另外一個接口。適配器讓本來接口不兼容的類能夠合做無間。
注:細分適配器類型是有兩種的,對象適配器和類適配器,前面的火雞例子是對象適配器,而「類」適配器則須要多重繼承才能實現,而Java中是不被容許的,這裏就不講述。
感謝你看到這裏,適配器模式到這裏就結束了,本人文筆隨便,如有不足或錯誤之處望給予指點,90度彎腰~~~很快我會發佈下一個設計模式的內容,生命不息,編程不止!
參考書籍:《Head First 設計模式》