適配器模式:如何讓不相容的介面變得相容

来源:https://www.cnblogs.com/waynaqua/archive/2023/09/08/17688134.html
-Advertisement-
Play Games

在軟體開發中,我們經常會遇到這樣的情況:我們需要使用一個現有的類或者介面,但它與我們系統的目標介面不相容,而我們又不能修改它。這時候,我們該怎麼辦呢?大多數情況下我們都可以使用適配器模式來解決這個問題,**本文將從以下四個方面講解適配器模式**。 - 簡介 - 優缺點 - 應用場景 - Java 代 ...


在軟體開發中,我們經常會遇到這樣的情況:我們需要使用一個現有的類或者介面,但它與我們系統的目標介面不相容,而我們又不能修改它。這時候,我們該怎麼辦呢?大多數情況下我們都可以使用適配器模式來解決這個問題,本文將從以下四個方面講解適配器模式

  • 簡介
  • 優缺點
  • 應用場景
  • Java 代碼示例

簡介

適配器模式(Adapter Pattern)是一種結構型設計模式,它可以將一個介面轉換成客戶端所期待的另一個介面,從而使原本由於介面不相容而不能一起工作的類可以一起工作。適配器模式也稱為包裝器模式(Wrapper Pattern),因為它通過一個包裝類(即適配器)來包裝不相容的介面,並提供統一的目標介面。適配器模式可以在運行時根據需要選擇不同的適配器來適配不同的被適配者。

對象適配器模式的各角色定義如下。

  • Target(目標介面):客戶端要使用的目標介面標準,對應下文中的三相插孔介面 TriplePin。
  • Adapter(適配器):實現了目標介面,負責適配(轉換)被適配者的介面 specificRequest()為目標介面 request(),對應本章下文中的電視機專屬適配器類 TriplePinAdapter。
  • Adaptee(被適配者):被適配者的介面標準,目前不能相容目標介面的問題介面,可以有多種實現類,對應下文中的兩相插孔介面 DualPin。
  • Client(客戶端):目標介面的使用者。

推薦博主開源的 H5 商城項目waynboot-mall,這是一套全部開源的微商城項目,包含三個項目:運營後臺、H5 商城前臺和服務端介面。實現了商城所需的首頁展示、商品分類、商品詳情、商品 sku、分詞搜索、購物車、結算下單、支付寶/微信支付、收單評論以及完善的後臺管理等一系列功能。 技術上基於最新得 Springboot3.0、jdk17,整合了 MySql、Redis、RabbitMQ、ElasticSearch 等常用中間件。分模塊設計、簡潔易維護,歡迎大家點個 star、關註博主。

github 地址:https://github.com/wayn111/waynboot-mall

優缺點

適配器模式的優點有:

  • 適配器模式可以增強程式的可擴展性,通過使用適配器,可以在不修改原有代碼的基礎上引入新的功能或者介面。
  • 適配器模式可以提高類的復用性,通過使用適配器,可以將已有的類或者介面重新組合和封裝,使其符合新的需求。
  • 適配器模式可以增加類的透明度,通過使用適配器,客戶端只需要關註目標介面,而無需瞭解被適配者的具體實現。
  • 適配器模式可以靈活地切換不同的被適配者,通過使用不同的適配器,可以動態地選擇不同的被適配者來滿足不同的場景。

適配器模式的缺點有:

  • 適配器模式會增加系統的複雜性,過多地使用適配器會使系統變得零亂和難以理解。
  • 適配器模式可能會降低系統的性能,因為每次調用目標介面時都需要經過適配器的轉換。
  • 適配器模式可能會違反開閉原則,如果目標介面發生變化,則需要修改所有的適配器類。

應用場景

適配器模式適用於以下場景:

  • 當需要在一個已有系統中引入新的功能或者介面時,它與系統的目標介面不相容,但又不能修改原有代碼時,可以使用適配器模式。例如在一個資料庫操作系統中,如果想要支持多種類型的資料庫源,但系統只提供了一個固定類型資料庫源的操作介面時,可以使用一個資料庫源操作適配器來將不同類型資料庫源轉換成統一類型資料庫源。
  • 當需要在多個獨立開發的系統或者組件之間進行協作時,但由於各自採用了不同的介面或者協議時,可以使用適配器模式。例如在一個分散式服務系統中,如果想要讓不同語言編寫的服務之間進行通信和調用,但各自採用了不同的通信協議和數據格式時,可以使用一個服務通信適配器來將不同協議和數據格式轉換成統一協議和數據格式。

Java 代碼示例

舉一個生活中常見的實例,我們新買了一臺電視機,其電源插頭是兩相的,不巧的是牆上的插孔卻是三相的,這時電視機便無法通電使用,我們以代碼來重現這個場景。

  1. 定義目標介面:三相插口 TriplePin,其中 3 個參數 l、n、e 分別對應火線(live)、零線(null)和地線(earth)。
public interface TriplePin {

    public void electrify(int l, int n, int e);
}
  1. 定義被適配者介面:兩項插口 DualPin,可以看到參數中缺少了地線 e 參數。
public interface DualPin {

    public void electrify(int l, int n);
}

  1. 添加被適配者介面具體實現類:TV,可以看到 TV 實現的是兩相介面,所在無法直接在三項介面中使用。
public class TV implements DualPin {
    @Override
    public void electrify(int l, int n) {
        System.out.println("火線通電:" + l + ",零線通電:" + n);
        System.out.println("電視開機");
    }
}

  1. 定義適配器類:三項介面適配器 TriplePinAdapter,實現了三項介面並且包含兩項介面屬性,在 electrify 方法中調用被適配設備的兩插通電方法,忽略地線參數 e,以此來完成三項介面對兩項介面的相容。

這也就意味著 TriplePinAdapter 類能幫助我們將 TV 類與三項介面相容。

public class TriplePinAdapter implements TriplePin {

    private DualPin dualPin;

    public TriplePinAdapter(DualPin dualPin) {
        this.dualPin = dualPin;
    }

    @Override
    public void electrify(int l, int n, int e) {
        // 調用被適配設備的兩插通電方法,忽略地線參數e
        dualPin.electrify(l, n);
    }
}
  1. 定義客戶端類
public class Client {

    public static void main(String[] args) {
        DualPin dualPinDevice = new TV();
        TriplePin triplePinDevice = new TriplePinAdapter(dualPinDevice);
        triplePinDevice.electrify(1, 0, -1);
    }
}

輸出結果如下:

火線通電:1,零線通電:0
電視開機

總結

通過利用適配器模式對系統進行擴展後,我們就不必再為解決相容性問題去暴力修改類介面了,轉而通過適配器,以更為優雅、巧妙的方式將兩側“對立”的介面“整合”在一起,順利化解雙方難以調和的矛盾,最終使它們順利接通。

關註公眾號【waynblog】每周分享技術乾貨、開源項目、實戰經驗、國外優質文章翻譯等,您的關註將是我的更新動力!


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

-Advertisement-
Play Games
更多相關文章
  • 此篇文章用於記錄柏成從零開發一個canvas九宮格手勢解鎖器的歷程。我們基於 canvas 實現了一款簡單的九宮格手勢解鎖器,用戶可以通過在九宮格中繪製特定的手勢來解鎖。 ...
  • ##一、定義 **使用原型實例指定待創建對象的類型,並且通過複製這個原型來創建新的對象。原型模式是一種創建型模式。** ##二、描述 **包含以下三個角色:** ![](https://img2023.cnblogs.com/blog/1780813/202305/1780813-202305271 ...
  • 本文給大家介紹了什麼是"編程範式",選擇合適的編程範式可以提高代碼的可讀性、可維護性和可擴展性。 一、 什麼是編程範式? "編程範式"是一種編程思想的總稱,它是指在編寫程式時所採用的基本方法和規範。常見的編程範式有面向對象、函數式、邏輯式等。 選擇合適的編程範式可以提高代碼的可讀性、可維護性和可擴展 ...
  • 淺聊一下SpringMVC的核心組件以及通過源碼瞭解其執行流程 MVC作為WEB項目開發的核心環節,正如三個單詞的分解那樣,Controller(控制器)將View(視圖、用戶客戶端)與Model(javaBean:封裝數據)分開構成了MVC,今天我們淺聊一下SpringMVC的相關組件以及通過源碼... ...
  • ### 原型模式 #### 案例引入 ##### 克隆羊問題 有一隻羊,姓名為tom,年齡為1,顏色為白色,編寫程式創建和tom羊屬性完全相同的羊。 ##### 傳統方式解決 代碼實現 ```java public class Sheep { private String name; private ...
  • 結構體(簡稱struct)用於創建不同數據類型的成員集合,放入一個單一的變數中。雖然數組用於將相同數據類型的多個值存儲在單一變數中,但結構體用於將不同數據類型的多個值存儲在單一變數中。結構體對於將數據組合在一起以創建記錄非常有用。 聲明結構體 要在Go中聲明一個結構體,請使用type和struct關 ...
  • ### 前言 上篇文章 [13分鐘聊聊併發包中常用同步組件並手寫一個自定義同步組件](https://juejin.cn/post/7274475842998042665) 聊到併發包中常用的同步組件,並且還手把手實現了自定義的同步組件 本篇文章來聊聊併發包下的另一個核心-線程池 閱讀本文大概12分 ...
  • # Python初步瞭解裝飾器 - 裝飾器的概念 - 裝飾器的簡單使用 - 裝飾器的進階 - 裝飾器的練習 - 裝飾器的固定模塊 - 裝飾器的語法糖 ## 裝飾器的概念 ```python 裝飾器它不是一個新的知識點,它是有之前我們學習的名稱空間、函數嵌套、閉包函數等知識點彙總而來 器:工具 裝飾: ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...