【設計模式】適配器模式(包裝器模式),缺省適配器模式,雙向適配器模式

適配器模式(Adapter Pattern)詳解

一、適配器模式簡介

適配器模式是一種結構型設計模式,它將一個類的接口轉換成客戶端所期望的另一個接口。適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以協同工作。

簡單來說,適配器模式就像是一個變壓器或者轉接頭,它可以幫助我們解決兩個不兼容接口之間的合作問題。

別名為**包裝器(Wrapper)**模式。

定義中所提及的接口是指廣義的接口,它可以表示一個方法或者方法的集合。

二、適用場景與針對的問題

  • 適用場景:當你需要使用一個已有的類,但是它的接口并不符合你的需求時;或者你需要創建一個可復用的類,該類能夠與其他不相關的類或不可預見的類(即那些接口可能不一定兼容的類)協同工作。
  • 針對的問題:主要是解決不同接口之間的不兼容性問題,使得它們能夠在不影響各自實現的情況下進行協作。

三、實際案例

想象一下,你有一臺筆記本電腦和一部手機,兩者都需要充電,但它們的充電插口不一樣。如果你只有一個電源適配器,這個適配器能將家用電源轉換為筆記本電腦所需的電壓和電流類型,但對于手機則無法直接使用。此時,你就需要一個USB-C到Lightning的適配器來為你的手機充電。這里,電源適配器和USB-C到Lightning適配器就起到了適配器的作用。

3.1 適配器模式的結構與實現

適配器模式的結構(類適配器)
在這里插入圖片描述

適配器模式的結構(對象適配器)
在這里插入圖片描述
適配器模式的結構
適配器模式包含以下3個角色:
Target(目標抽象類)
Adapter(適配器類)
Adaptee(適配者類)

四、代碼案例

假設有一個MediaPlayer接口和其實現類AudioPlayer,它只能播放mp3格式的音頻文件。現在我們需要擴展其功能以支持更多格式如VLC和MP4,但不想改變原有的AudioPlayer類。這時就可以使用適配器模式。

// 目標接口
interface MediaPlayer {public void play(String audioType, String fileName);
}// 已有類,實現了不同的接口
class AdvancedMediaPlayer {public void playVlc(String fileName) {System.out.println("Playing vlc file. Name: " + fileName);}public void playMp4(String fileName) {System.out.println("Playing mp4 file. Name: " + fileName);}
}// 適配器類
class MediaAdapter implements MediaPlayer {private AdvancedMediaPlayer advancedMusicPlayer;public MediaAdapter(String audioType) {if (audioType.equalsIgnoreCase("vlc")) {advancedMusicPlayer = new AdvancedMediaPlayer();} else if (audioType.equalsIgnoreCase("mp4")) {advancedMusicPlayer = new AdvancedMediaPlayer();}}@Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase("vlc")) {advancedMusicPlayer.playVlc(fileName);} else if (audioType.equalsIgnoreCase("mp4")) {advancedMusicPlayer.playMp4(fileName);}}
}// 使用適配器的類
class AudioPlayer implements MediaPlayer {MediaAdapter mediaAdapter;@Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase("mp3")) {System.out.println("Playing mp3 file. Name: " + fileName);} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {mediaAdapter = new MediaAdapter(audioType);mediaAdapter.play(audioType, fileName);} else {System.out.println("Invalid media. " + audioType + " format not supported");}}
}// 測試類
public class Test {public static void main(String[] args) {AudioPlayer audioPlayer = new AudioPlayer();audioPlayer.play("mp3", "beyond the horizon.mp3");audioPlayer.play("mp4", "alone.mp4");audioPlayer.play("vlc", "far far away.vlc");audioPlayer.play("avi", "mind me.avi");}
}

在這個例子中,MediaAdapter充當了適配器的角色,它將AdvancedMediaPlayer的功能適配到了MediaPlayer接口上,從而解決了接口不兼容的問題。通過這種方式,我們可以輕松地擴展AudioPlayer的功能,讓它支持更多的音頻格式。

五、缺省適配器模式

  • 定義:當不需要實現一個接口所提供的所有方法時,可先設計一個抽象類實現該接口,并為接口中每個方法提供一個默認實現(空方法),那么該抽象類的子類可以選擇性地覆蓋父類的某些方法來實現需求,它適用于不想使用一個接口中的所有方法的情況,又稱為單接口適配器模式。
  • 結構
    在這里插入圖片描述- 實現
    缺省適配器類的典型代碼片段(C++):
abstract class AbstractServiceClass : ServiceInterface
{public void ServiceMethod1() {  }  //空方法public void ServiceMethod2() {  }  //空方法public void ServiceMethod3() {  }  //空方法
}

六、雙向適配器模式

  • 結構
    在這里插入圖片描述
  • 實現
public class Adapter : Target, Adaptee 
{//同時維持對抽象目標類和適配者的引用private Target target;private Adaptee adaptee;public Adapter(Target target) {this.target = target;}public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}public void Request() {adaptee.SpecificRequest();}public void SpecificRequest() {target.Request();}
}

七、適配器模式的優缺點與適用環境

  • 模式適用環境:系統需要使用一些現有的類,而這些類的接口不符合系統的需要,甚至沒有這些類的源代碼
    創建一個可以重復使用的類,用于和一些彼此之間沒有太大關聯的類,包括一些可能在將來引進的類一起工作

  • 模式優點
    將目標類和適配者類解耦,通過引入一個適配器類來重用現有的適配者類,無須修改原有結構
    增加了類的透明性和復用性,提高了適配者的復用性,同一個適配者類可以在多個不同的系統中復用
    靈活性和擴展性非常好
    類適配器模式:置換一些適配者的方法很方便
    對象適配器模式:可以把多個不同的適配者適配到同一個目標,還可以適配一個適配者的子類

  • 模式缺點
    類適配器模式:(1) 一次最多只能適配一個適配者類,不能同時適配多個適配者;(2) 適配者類不能為最終類;(3) 目標抽象類只能為接口,不能為類
    對象適配器模式:在適配器中置換適配者類的某些方法比較麻煩

經典運用:
Sun公司在1996年公開了Java語言的數據庫連接工具JDBC,JDBC使得Java語言程序能夠與數據庫連接,并使用SQL語言來查詢和操作數據。JDBC給出一個客戶端通用的抽象接口,每一個具體數據庫引擎(如SQL Server、Oracle、MySQL等)的JDBC驅動軟件都是一個介于JDBC接口和數據庫引擎接口之間的適配器軟件。抽象的JDBC接口和各個數據庫引擎API之間都需要相應的適配器軟件,這就是為各個不同數據庫引擎準備的驅動程序。

部分內容由AI大模型生成,請注意識別!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88902.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88902.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88902.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

安全初級(一)

一.docker的搭建和VPN連接 1.輸入指令:apt-get install docker.io docker-compose 2.設置docker代理:創建文件夾以及對應的文件 /etc/systemd/system/docker.service.d/http-proxy.conf 在該文件中配置自己的代理ip以及代理端口 [Service] Environme…

Java多線程:核心技術與實戰指南

目錄🚀前言🤔什么是多線程?💻創建線程💯創建方法一:繼承Thread類💯創建方法二:實現Runnable接口💯創建方法三:實現Callable接口💯三種方法對比&am…

高斯代數基本定理的一種證明

代數基本定理 對于多項式 f(z)anznan?1zn?1?a1za0f(z) a_n z^n a_{n-1} z^{n-1} \cdots a_1 z a_0f(z)an?znan?1?zn?1?a1?za0?(其中 n>1n > 1n>1 且 an,a0≠0a_n, a_0 \neq 0an?,a0?0),它在復數域內有根。 f(z)U…

【K8S】Kubernetes 使用 Ingress-Nginx 基于 Cookie 實現會話保持的負載均衡

文章目錄 1. 創建測試應用 Deployment3. 配置基于 Cookie 的 Ingress4. 部署與測試步驟(1) 應用配置(2) 獲取 Ingress IP(3) 測試會話保持(4) 使用 Nginx 取消域名的限制(僅推薦測試使用)5、生產優化建議6、獨立 Nginx 配置參考在現代微服務架構中,負載均衡是保證高可用的關…

2.查詢操作-demo

在連接數據庫的基礎上步驟:Query-查詢關閉查詢db.Next()逐行輸出,并指定到當前變量Scan-掃描rows, err : db.Query("SELECT id,server_ip FROM softswitch_server_info")package main//查詢語句-demo //關鍵字-queryimport ("database/sq…

用OpenCV標定相機內參應用示例(C++和Python)

下面是一個完整的 使用 OpenCV 進行相機內參標定(Camera Calibration) 的示例,包括 C 和 Python 兩個版本,基于棋盤格圖案標定。一、目標:相機標定 通過拍攝多張帶有棋盤格圖案的圖像,估計相機的內參&#…

(二)OpenCV——邊緣增強與檢測

邊緣增強與檢測是圖像處理中的核心技術,其核心目標是突出圖像中的不連續區域(邊緣),為后續的圖像分析提供基礎。一、基本概念邊緣本質上是圖像中灰度/顏色發生突變的區域,對應著:物體邊界表面方向改變材質變…

018 進程控制 —— 進程等待

🦄 個人主頁: 小米里的大麥-CSDN博客 🎏 所屬專欄: Linux_小米里的大麥的博客-CSDN博客 🎁 GitHub主頁: 小米里的大麥的 GitHub ?? 操作環境: Visual Studio 2022 文章目錄進程控制 —— 進程等待1. 進程等待必要性2. 常用等待方法&#xf…

PHP password_hash() 函數

password_hash() 函數用于創建密碼的散列(hash)PHP 版本要求: PHP 5 > 5.5.0, PHP 7語法string password_hash ( string $password , int $algo [, array $options ] )password_hash() 使用足夠強度的單向散列算法創建密碼的散列(hash&…

理解Linux文件系統:從物理存儲到統一接口

目錄 一、狹義理解(物理層面) 二、廣義理解(Linux系統視角) 三、文件結構解析 四、系統實現機制 一、狹義理解(物理層面) 存儲特性:文件以二進制形式存儲在磁盤等永久性存儲介質中 介質特點…

前端接入海康威視攝像頭的三種方案

方案選擇?方案適用場景優缺點?Web SDK(3.0)??需要完整功能(PTZ控制、錄像回放)功能全,但需加載海康JS文件?RTSP轉Web播放?低延遲實時監控需后端轉碼(如FFmpeg轉HLS)?HTTP API?簡單截圖或…

openGL學習(Shader)

認識Shader在計算機圖形學中,Shader(著色器)是一種運行在 GPU(圖形處理單元)上的程序,用于控制圖形渲染過程中頂點和像素的處理。著色器是 OpenGL、Direct3D、Vulkan 等圖形 API 的核心組成部分&#xff0c…

webpack高級配置

一、了解webpack高級配置: 1、什么是webpack高級配置: 進行 Webpack 優化,讓代碼在編譯或者運行時性能更好 2、webpack優化從哪些方面入手: ① 提升開發體驗,增強開發和生產環境的代碼調試: 如果代碼編寫…

LLM表征工程還有哪些值得做的地方

LLM表征工程還有哪些值得做的地方 在大型語言模型(LLM)的表征工程領域,近年來涌現出多個具有突破性的創新方向,這些方法通過動態調整、多模態融合、結構化記憶增強等技術,顯著提升了模型的適應性、可解釋性和效率。 一、動態自適應表征:從靜態到動態的范式革新 傳統LL…

LabVIEW智能避障小車

?LabVIEW結合 NI、德州儀器(TI)、歐姆龍(Omron)等硬件,設計實現了一款具備智能避障、循跡功能的輪式機器人。系統支持手動操控與自主運行兩種模式,通過無線通信實時傳輸傳感器數據與圖像信息,在…

邏輯代數中的基本規則,代入規則和反演規則,對偶規則

本文探討了代入規則在邏輯等式中的應用,解釋了如何通過替換變量來保持等式的正確性,同時介紹了反演規則和對偶規則的概念。代入規則定義:在任何一個包含變量A的邏輯等式中,如果用另一個邏輯式代入式中的所有A位置,則等式依然成立反…

Javaweb使用websocket,請先連上demo好吧!很簡單的!

Javaweb使用websocket先看結構及效果MyWebSocketHandler用于處理消息WebSocketConfig用于配置建聯地址等SchedulerConfig必須配置這個MyWebSocketInterceptor建聯的攔截器SpringBootWebsocketApplication啟動類POM依賴展示效果源碼先看結構及效果 MyWebSocketHandler用于處理消…

文心大模型4.5開源測評:保姆級部署教程+多維度測試驗證

前言:國產大模型開源的破局時刻 2025年6月百度文心大模型4.5系列的開源,標志著國產AI從"技術跟跑"向"生態共建"的關鍵跨越。 文心大模型4.5是百度自主研發的新一代原生多模態基礎大模型,通過多個模態聯合建模實現協同優…

前端學習5:Float學習(僅簡單了解,引出flex)

一、Float基礎概念1. 設計初衷: float最初是為實現文字環繞圖片的效果(類似雜志排版),后來被開發者用來做頁面布局。2. 核心特性:使元素脫離普通文檔流(但仍在DOM中)元素會向左/右浮動&#xff…

08-自然壁紙實戰教程-視頻列表-云

08-自然壁紙實戰教程-視頻列表 前言 視頻列表頁面本質上也是一個數據展示的列表,不同之處在于之前是是展示壁紙,Image組件負責渲染,這里展示的是視頻,使用Video組件,另外視頻頁面也實現了下載的基本功能,…