一、基本介紹 之所以要寫適配器模式(二),是因為想強化一下練習。 而且在SpringMVC中有很多處理器適配器。 裡面的源碼包括一些特定的代碼結構,例如isSupport()方法。 也就是說適配器還可以這麼來用: 使得原本由於介面不相容而不能一起工作、不能統一管理的那些類可以在一起工作、可以進行統一 ...
一、基本介紹
之所以要寫適配器模式(二),是因為想強化一下練習。
而且在SpringMVC中有很多處理器適配器。
裡面的源碼包括一些特定的代碼結構,例如isSupport()
方法。
也就是說適配器還可以這麼來用: 使得原本由於介面不相容而不能一起工作、不能統一管理的那些類可以在一起工作、可以進行統一管理。
二、案例
需求: 廚師的工作是
cook()
,程式員的工作是program()
,司機的工作是drive()
,教師的工作是teach()
,不同的工種,其具體工作內容不同。現在程式要將這些很多個 不同工種的工作內容全部輸出。
兩種解決方案,其中使用適配器的又可以分為兩種。
- 解決方案一: 逐個訪問每個工種對象的相應工作方法。無法迴圈遍歷,無法統一管理。
- 解決方案二: 使用適配器模式,將這些不相容的具體工作轉換成一個統一的工作。實現迴圈遍歷。
為了代碼簡單,這裡只寫兩個工種。cooker
和programer
。
1、不使用適配器模式
若不使用適配器模式,則調用者需要定義出所有的工種對象, 然後逐個工種對象的工作方法進行調用。有 30 個工種,就應調用 30 個工作方法。很麻煩。
結構如下:
1.png先看兩個工種和實現類代碼:
public interface ICooker { String cook(); } /** * ICooker的實現類 :黃燜雞廚師 */ public class HmJCooker implements ICooker{ @Override public String cook() { return "製作黃燜雞!"; } } public interface IProgrammer { String programme(); } /** * 程式員的實現類: 京東的程式員 */ public class JDProgrammer implements IProgrammer { @Override public String programme() { return "編寫京東的網站!"; } }
測試:
/** * 這就是為什麼要使用 適配器模式 * 這樣的話 如果有很多介面的話,就會使得遍歷非常的麻煩 */ public class MyTest { public static void main(String[] args) { ICooker iCooker = new HmJCooker(); IProgrammer iProgrammer = new JDProgrammer(); //上報自己的職責 不能迴圈遍歷 System.out.println(iCooker.cook()); System.out.println(iProgrammer.programme()); } }
2、只定義一個適配器實現類
這種方式類似於多功能充電器,一個電源插頭上接著多種類型的充電介面。用戶在使用時需要使用電器介面與多功能充電器上的充電介面逐個進行對比,介面匹配,則可以充電。
22.png代碼:
public class WorkAdapter{ public String work(Object worker) { String workContent = ""; // 若傳來的對象是廚師,就調用cook()方法 if(worker instanceof ICooker){ workContent = ((ICooker)worker).cook(); } if(worker instanceof IProgrammer){ workContent = ((IProgrammer)worker).programme(); } return workContent; } }
測試類(可以實現迴圈遍歷):
public class MyTest { public static void main(String[] args) { //這個是兩個工作者 ICooker iCooker = new HmJCooker(); IProgrammer iProgrammer = new JDProgrammer(); Object[] workers = {iCooker, iProgrammer}; //創建設配器對象 WorkAdapter adapter = new WorkAdapter(); //讓每個工種對象在設配器中進行匹配 for (Object worker : workers) { String workContent = adapter.work(worker); System.out.println(workContent); } } }
輸出:
製作黃燜雞!
編寫京東的網站!
3、為每個工種定義一個適配器類
這種用的最多。因為不同的電器需要不同的充電器。(很少上面這種組合充電器),而且SpringMVC裡面也是用的這種方式。
3.png代碼:
/** 統一的 介面適配器 */ public interface IWorkerAdapter { String work(Object worker); //只能放Object,因為傳進來的可以實現不同的介面 boolean isSupport(Object worker); }
廚師的適配器:
public class CookerAdapter implements IWorkerAdapter{ @Override public String work(Object obj) { return ((ICooker)obj).cook(); } @Override public boolean isSupport(Object worker) { return (worker instanceof ICooker); } }
程式員的適配器:
public class ProgrammerAdapter implements IWorkerAdapter { @Override public String work(Object worker) { return ((IProgrammer)worker).programme(); } @Override public boolean isSupport(Object worker) { return worker instanceof IProgrammer; } }
測試:
public class MyTest { static List<IWorkerAdapter> adapters; public static void main(String[] args) { //這個是兩個工作者 ICooker iCooker = new HmJCooker(); IProgrammer iProgrammer = new JDProgrammer(); Object[] workers = {iCooker, iProgrammer}; //添加所有的適配器 adapters = new ArrayList<>(); adapters.add(new CookerAdapter()); adapters.add(new ProgrammerAdapter()); //讓每個工種對象在設配器中進行匹配 for (Object worker : workers) { IWorkerAdapter adapter = getAdapter(worker); // 獲取對應的適配器 String workContent = adapter.work(worker); // 對應的適配器進行對應的充電吧 System.out.println(workContent); } } //獲取指定的某個適配器 static IWorkerAdapter getAdapter(Object worker) { for (IWorkerAdapter adapter : adapters) { if (adapter.isSupport(worker)) { return adapter; } } return null; } }
輸出和上面一樣。
三、總結
從這種角度來看,適配器不是冒充,而是實現統一管理。
免費Java高級資料需要自己領取,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高併發分散式等教程,一共30G。
傳送門:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q