設計模式——介面卡(Adapter)模式
- 概述
什麼是介面卡?在我們生活中的介面卡比如插頭轉換器(中標轉美標)、USB介面轉換器(type-c轉蘋果),電腦電源介面卡(交流電轉低電壓直流)等。像這種將兩者有差異的東西通過介面卡使他們成為相互適合的東西。在程式世界中,經常存在現有的程式無法直接使用,需要做適當的變換後才能使用的情況,這種用於填補“現有程式”和“所需程式”之間差異的設計模式就是介面卡(Adapter)模式。介面卡模式有類介面卡模式和物件介面卡模式兩種,前者使用繼承,後者使用組合,所以後者比較靈活,推薦使用。下面通過例項對這兩種模式的學習做一個筆記。
- 例項
類介面卡模式
Banner類:代表現在的實際情況
/** * 注意:兩種實現方式都是用的這個Banner類 * 推薦使用物件介面卡方式 */ public class Banner { private String string; public Banner(String string) { this.string = string; } /** * 用括號將字串括起來 */ public void showWithParen(){ System.out.println("("+string+")"); }/** * 用星號將字串括起來 */ public void showWithAster(){ System.out.println("*"+string+"*"); } }
PrintForClass介面:代表是“需求”的介面
public interface PrintForClass { public abstract void printWeak(); public abstract void printStrong(); }
PrintBannerForClass類:扮演適配的角色。
實現目標介面(PrintForClass)達到適配目的,而繼承被適配者類(Banner)達到通過呼叫被適配者裡的方法來實現目標介面的功能。
public class PrintBannerForClass extends Banner implements PrintForClass{ public PrintBannerForClass(String string) { super(string); } //實現PrintForClass中的方法 @Override public void printWeak() { super.showWithParen(); } @Override public void printStrong() { super.showWithAster(); } }
Main類:通過扮演介面卡角色的PrintBannerForClass類來顯示字串。
注意:這裡我們將PrintBannerForClass類的例項儲存在了PrintForClass型別的變數中。在這個類中,我們是使用PrintForClass介面來進行程式設計的。對Main類來說,Banner類、showWithParen()、showWithAster()方法被完全隱藏起來了。這就好像電腦電源介面卡(交流電轉低電壓直流),電腦使用的是直流電,而它並不關心這個直流電是怎麼來的。
public class Main { public static void main(String[] args) { //使用類介面卡模式(繼承) PrintForClass p = new PrintBannerForClass("Hello World!"); p.printWeak(); p.printStrong(); } }
物件介面卡模式(推薦)
物件介面卡模式就是採用一種“委託”的方式將某個方法中的實際處理交給其它例項來處理。在下面的例子中就是當PrintBannerForObject類中的printWeak()方法被呼叫的時候,並不是PrintBannerForObject類自己進行處理,而是將處理交給了Banner類的例項的showWithParen()方法。
Banner類:和上面的Banner類一樣
PrintForObject類:不同於使用類介面卡模式,這裡使用的類,而類適配模式是使用的介面。
public abstract class PrintForObject { public abstract void printWeak(); public abstract void printStrong(); }
PrintBannerForObject類:這個類中的banner欄位儲存了Banner的例項。然後printWeak()方法和printStrong()方法通過這個例項物件呼叫Banner類中的方法實現具體的功能。
public class PrintBannerForObject extends PrintForObject { private Banner banner; public PrintBannerForObject(String string) { this.banner = new Banner(string); } //實現PrintForObject中的方法 @Override public void printWeak() { banner.showWithParen(); } @Override public void printStrong() { banner.showWithAster(); } }
- 完整程式碼
請移步:https://github.com/yyc007/DesignPatterns/
- 小結
介面卡模式就是將一個類的介面轉換成另一種介面,讓原本介面不相容的類可以相容。
從使用者的角度看不到被適配者,是解耦的;
使用者呼叫介面卡轉化出來的目標介面方法;
介面卡再呼叫被適配者的相關介面方法;
使用者收到反饋結果,感覺只是和目標介面互動。