JAVA設計模式之適配器模式

来源:https://www.cnblogs.com/luohanguo/archive/2019/01/29/10334291.html
-Advertisement-
Play Games

1 初步認識 適配器模式的定義 將一個類的介面轉成客戶期望的另外一個介面。適配器模式使得原本由於介面不匹配而不能一起工作的那些類可以一起工作。 大白話 適配器模式就像旅行插座轉換器(圖1)、Type-c轉VGA轉介面(圖4)一樣。 圖1. 圖片來源網路 圖2. 圖片來源網路 去過香港迪拜等的同學都知 ...


1 初步認識

適配器模式的定義

  將一個類的介面轉成客戶期望的另外一個介面。適配器模式使得原本由於介面不匹配而不能一起工作的那些類可以一起工作。

大白話

  適配器模式就像旅行插座轉換器(圖1)、Type-c轉VGA轉介面(圖4)一樣。

 

1. 圖片來源網路

2. 圖片來源網路

  去過香港迪拜等的同學都知道,那邊用的插座跟我們不一樣,他們的插座需要如圖2第1面所示的插頭,而我們常用的插座類似第2面。因此我們的筆記本電腦,手機在當地不能直接充電。所以就需要一個插座轉換器,轉換器第1面插入當地的插座,第2面供我們充電,這樣使得我們的插頭在當地能使用。Type-c轉VGA轉介面也是一樣的道理。

2 適配器模式結構圖

3. 適配模式結構圖 來源網路

  如圖所示,Client不能直接訪問Adaptee。Adapter是適配器,它將Adaptee轉換成Client能訪問的介面。所以通過適配器Adapter,用戶端就可以訪問Adaptee。

3 使用場景例子

  手機想要投影到投影儀上,由於手機是Type-c介面,投影儀是VGA介面。不能直接投影,需要一個適配器,將視頻信號從Type-c口轉到VGA口,最後才能輸出到大屏幕上。

4 適配器模式在使用場景的具體實現

圖4. typec轉vga/hdm轉換器

 

  如圖所示,這有一個適配器,一號口是typec口,二號口是vga口,只有將視頻信號從typec口輸入,轉換輸出到vga口,才能和投影儀對接,實現手機屏幕投影到投影儀上的任務。涉及的物品有:手機、適配器、投影儀。

  4.1 定義一個手機,它有個typec口,這是視頻源。

package com.jstao.adapter;

/**
 * @author jstao
 * 定義一個手機Phone,它有一個Typec介面。
 * 
 */
public class Phone {
    public void typecPhone() {
        System.out.println("信息從Typec口的手機輸出。");
    }
}

  4.2 定義一個vga介面

package com.jstao.adapter;

/**
 * @author jstao
 * 定義一個VGA介面。
 * 
 */
public interface Vga {
    void vgaInterface();
}

  4.3 實現一個適配器,適配器實現方式分三類:類的適配器模式、對象的適配器模式、介面的適配器模式。

  4.3.1 類的適配器模式

  原理:通過繼承特性來實現適配器功能。

package com.jstao.adapter;

/**
 * 
 * 實現一個Type-c轉VGA適配器,
 * 適配器實現方式有三種,這是第一種實現方式。
 * @author jstao
 *
 */
public class Typec2Vga1 extends Phone implements Vga{
    @Override
    public void vgaInterface() {
        // TODO Auto-generated method stub
        typecPhone();
        System.out.println("接收到Type-c口信息,信息轉換成VGA介面中...");
        System.out.println("信息已轉換成VGA介面,顯示屏可以對接。");
    }
}

  4.3.2 對象的適配器模式

  原理:通過組合方式來實現適配器功能。

package com.jstao.adapter;

/**
 * 
 * 實現一個Type-c轉VGA適配器,
 * 適配器實現方式有三種,這是第二種實現方式。
 * @author jstao
 *
 */
public class Typec2Vga2 implements Vga{

    private Phone phone;
    
    public Typec2Vga2(Phone phone) {
        // TODO Auto-generated constructor stub
        this.phone = phone;
    }
    
    @Override
    public void vgaInterface() {
        // TODO Auto-generated method stub
        if(phone != null) {
            phone.typecPhone();
            System.out.println("接收到Type-c口信息,信息轉換成VGA介面中...");
            System.out.println("信息已轉換成VGA介面,顯示屏可以對接。");
        }
    }
}

  4.3.3 介面的適配器模式

  原理:藉助抽象類來實現適配器功能。

  定義三個介面

package com.jstao.adapter;

/**
 * 定義介面
 * @author jstao
 *
 */
public interface Target {
    
    void typec();
    void typec2vga();
    void typec2hdmi();
}

  定義一個抽象類

package com.jstao.adapter;

/**
 * 定義一個抽象類
 * @author jstao
 *
 */
public abstract class Adapter implements Target{

    public void typec() { }
    
    public void typec2vga() { }
    
    public void typec2hdmi() { }
}

  實現一個VGA適配器

package com.jstao.adapter;

/**
 * 
 * 實現一個VGA適配器,同理還可以實現一個HDMI適配器
 * 適配器實現方式有三種,這是第三種實現方式。
 * @author jstao
 *
 */
public class VgaAdapter extends Adapter{
    
    public void typec() {
        System.out.println("信息從Typec口的手機輸出。");
    }
    
    public void typec2vga() {
        System.out.println("接收到Type-c口信息,信息轉換成VGA介面中...");
        System.out.println("信息已轉換成VGA介面,顯示屏可以對接。");
    }
}

  4.4 定義一個顯示屏,用來測試上面實現的三個適配器

package com.jstao.adapter;

/**
 * 定義一個顯示屏
 * 與適配器對接
 * @author jstao
 *
 */
public class Screen {
    public static void main(String[] args) {
        //第一種適配器用法
        System.out.println("-------------第一種適配器------------");
        Vga vga = new Typec2Vga1();
        vga.vgaInterface();//適配器將typec轉換成vga
        System.out.println("顯示屏對接適配器,手機成功投影到顯示屏!");
        
        //第二種適配器用法
        System.out.println("-------------第二種適配器------------");
        Typec2Vga2 typec2Vga1 = new Typec2Vga2(new Phone());
        typec2Vga1.vgaInterface();//適配器將typec轉換成vga
        System.out.println("顯示屏對接適配器,手機成功投影到顯示屏!");
        
        //第三種適配器用法
        System.out.println("-------------第三種適配器------------");
        VgaAdapter vgaAdapter = new VgaAdapter();
        vgaAdapter.typec();
        vgaAdapter.typec2vga();//適配器將typec轉換成vga
        System.out.println("顯示屏對接適配器,手機成功投影到顯示屏!");
    }
}

  4.5 測試結果

圖5. 結果輸出圖

  可以看到,得到的結果都一樣,但是三種適配器的實現的方式卻不相同。

5 小結

  5.1 適配器模式在源碼中的應用:

  (1)JDK源碼的IO模塊用到,例如 java.io.InputStreamReader(InputStream)、java.io.OutputStreamWriter(OutputStream)。

  (2)mybatis源碼日誌模塊用到對象適配器模式。

  5.1 適配器模式將一個介面轉為另外一個介面。它有三種實現方式:

  (1)當希望將一個類轉換為滿足另一個新介面的類時,可以使用類的適配器模式,創建一個新類,繼承原有的類,實現新的介面即可,例如4.3.1。

  (2) 當希望將一個對象轉換成滿足另一個新介面的對象時,可以創建一個Typec2Vga2 類,持有原類的一個實例,在Typec2Vga2 類的方法中,調用實例的方法就行,例如4.3.2對象的適配器模式。

  (3)當不希望實現一個介面中所有的方法時,可以創建一個抽象類Adapter ,實現所有方法,我們寫別的類的時候,繼承抽象類即可,例如4.3.3介面的適配器模式。

6 我的其他JAVA設計模式

  (1)JAVA設計模式之策略模式

  (2)JAVA設計模式之觀察者模式


  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 包括7大設計原則和23大設計模式。7大設計原則這7大設計原則不僅是23大設計模式要去遵守的,也是我們平常開發過程中要時刻去遵守的準則,所以說非常非常重要。1,單一職責原則1)定義:就一個類而言,應該僅有一個引起它變化的原因。簡而言之,就是功能要單一。2)如果一個類承擔的職責過多,就等於把這些職責耦合... ...
  • 軟體設計模式 為了更好地理解依賴註入的概念,首先瞭解一下軟體設計模式是很有必要的。軟體設計模式主要用來規範問題及其解決方案的描述,以簡化開發人員對常見問題及其對應解決方案的標識與交流。 控制反轉IOC 幾乎每個人都看過或是自己寫過下麵代碼的經歷 1 public class EmailService ...
  • 下麵給出簡單的代碼,這裡通過將變數重置為零來實現過濾欄位的目的: 如果不希望使用二次映射,可以考慮使用reflect庫中,Value結構體的FieldByName成員函數。 ...
  • 適配器模式的定義:將一個類的介面變換成客戶端所期待的另一種介面,從而使原本因介面不匹配而無法在一起工作的兩個類能夠一起工作。 圖解: A、B兩個圖框代表已經塑模成型的物體A和物體B,現在要求把A和B安裝在一起使用,如何安裝?兩者的介面不一致,是不可能安裝在一起使用的,那怎麼辦?引入一個物體C,如下: ...
  • 初學laravel常常看到諸如依賴註入、控制反轉等名詞一臉懵逼,望而生畏,用了一段時間後才明白這些基本的原理,原理其實並不難,關鍵在於怎麼理解。 ...
  • 單一職責原則(Single Responsibility Principle),簡稱SRP。 定義:一個類只負責一件事情; 說明:類的單一職責原則受多重因素制約,實際實現起來,需要考慮項目工期、成本、人員技術水平等 使用:介面一定要做到單一職責原則,類的設計儘量做到單一職責原則 擴展:單一職責原則同 ...
  • 困擾 Intellij idea是一款非常強大的編輯器,可以很方便地幫我們創建maven項目,有用過的同學應該都深有體會,但我們經常會遇到一個困擾,那就是用idea創建maven項目時,速度很慢,往往需要好幾分鐘的時間,有時甚至會卡住,主要原因是創建maven項目時預設是下載求網路上的一個文件arc ...
  • 如果這是第二次看到我的文章,歡迎右側掃碼訂閱我喲~ 👉 本文長度為3012字,建議閱讀8分鐘。 堅持原創,每一篇都是用心之作~ 下麵的這個場景你可能會覺得很熟悉(Z哥我又要出演了): Z哥:@All 兄弟姐妹們,這次我這邊有個需求需要給「商品上架」增加一道審核,會影響到大家和我交互的介面。大家抽空 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...