当前位置: 首页 > news >正文

适配器模式适用的场景

适配器模式是一种常用的设计模式,能够将不兼容的接口转换为客户端所需的接口。在实际开发中,我们常常会遇到需要统一接口、替换外部系统、兼容旧接口或适配不同数据格式的情况。本文将结合详细的代码示例,介绍适配器模式的适用场景。

1. 统一多个类的接口设计

当一个功能的实现依赖于多个外部系统或类时,可以使用适配器模式将它们的接口适配为统一的接口定义。这样可以简化代码,使得调用者只需关注统一的接口。

示例:

// 统一接口
interface Payment {void pay(int amount);
}// 外部系统A
class Alipay {void makePayment(int amount) {System.out.println("Paid " + amount + " using Alipay.");}
}// 外部系统B
class WeChatPay {void payMoney(int amount) {System.out.println("Paid " + amount + " using WeChat Pay.");}
}// 适配器实现(针对 Alipay)
class AlipayAdapter implements Payment {private Alipay alipay;public AlipayAdapter(Alipay alipay) {this.alipay = alipay; // 将外部系统A注入适配器}@Overridepublic void pay(int amount) {alipay.makePayment(amount); // 调用外部系统A的方法}
}// 适配器实现(针对 WeChatPay)
class WeChatPayAdapter implements Payment {private WeChatPay weChatPay;public WeChatPayAdapter(WeChatPay weChatPay) {this.weChatPay = weChatPay; // 将外部系统B注入适配器}@Overridepublic void pay(int amount) {weChatPay.payMoney(amount); // 调用外部系统B的方法}
}

解释:
在这个示例中,Payment 接口是统一的支付接口,而 AlipayWeChatPay 是两个不同的支付系统。通过 AlipayAdapterWeChatPayAdapter,我们能够将这两个外部系统的接口适配为 Payment 接口,使得客户端只需调用 pay 方法即可。

2. 需要依赖外部系统时

当项目中依赖的外部系统需要替换时,利用适配器模式可以减少对代码的改动。这种方式让我们在替换外部系统时,只需更换适配器实现,而不需要修改客户端代码。

示例:

// 外部系统C
class PayPal {void executePayment(int amount) {System.out.println("Paid " + amount + " using PayPal.");}
}// 适配器实现
class PayPalAdapter implements Payment {private PayPal payPal;public PayPalAdapter(PayPal payPal) {this.payPal = payPal; // 将PayPal注入适配器}@Overridepublic void pay(int amount) {payPal.executePayment(amount); // 调用PayPal的方法}
}// 客户端代码
public class PaymentProcessor {private Payment payment;public PaymentProcessor(Payment payment) {this.payment = payment; // 注入适配器}public void processPayment(int amount) {payment.pay(amount); // 使用适配器进行支付}
}

解释:
在这个示例中,PaymentProcessor 类依赖于 Payment 接口,而不是直接依赖具体的支付实现。这样当我们想要替换支付系统(比如从 WeChatPay 替换为 PayPal)时,只需将相应的适配器传入 PaymentProcessor 的构造函数,而无需修改其内部逻辑。

3. 原有接口无法修改或功能过于老旧

在某些情况下,我们无法修改原有接口,或者原有接口的功能太老旧但又需要兼容。适配器模式可以帮助我们保留旧接口,并将其实现替换为更现代的接口。

示例:

// 老旧接口
interface OldList {void addElement(String element);
}// 新接口
interface NewList {void add(String item);
}// 新实现
class NewArrayList implements NewList {@Overridepublic void add(String item) {System.out.println("Added " + item + " to the new list.");}
}// 适配器实现
class OldListAdapter implements OldList {private NewList newList;public OldListAdapter(NewList newList) {this.newList = newList; // 将新接口注入适配器}@Overridepublic void addElement(String element) {newList.add(element); // 将老旧接口的方法调用转发到新接口}
}

解释:
在这个例子中,OldList 是一个过时的接口,而 NewList 是一个更新的接口。OldListAdapter 适配器通过将调用转发到 NewList 实现来实现兼容性,从而在使用旧接口的地方依然可以使用新功能。

4. 适配不同数据格式时

适配器模式在需要处理不同数据格式时特别有用。例如,Slf4j日志框架定义了打印日志的统一接口,并提供针对不同日志框架的适配器。

示例:

// 统一的日志接口
interface Logger {void log(String message);
}// 日志框架A
class Log4jLogger {void logMessage(String message) {System.out.println("Log4j: " + message);}
}// 日志框架B
class LogbackLogger {void writeLog(String message) {System.out.println("Logback: " + message);}
}// 适配器实现(针对 Log4j)
class Log4jAdapter implements Logger {private Log4jLogger log4jLogger;public Log4jAdapter(Log4jLogger log4jLogger) {this.log4jLogger = log4jLogger; // 将 Log4jLogger 注入适配器}@Overridepublic void log(String message) {log4jLogger.logMessage(message); // 调用 Log4j 的日志方法}
}// 适配器实现(针对 Logback)
class LogbackAdapter implements Logger {private LogbackLogger logbackLogger;public LogbackAdapter(LogbackLogger logbackLogger) {this.logbackLogger = logbackLogger; // 将 LogbackLogger 注入适配器}@Overridepublic void log(String message) {logbackLogger.writeLog(message); // 调用 Logback 的日志方法}
}

解释:
在这个例子中,Logger 是统一的日志接口,而 Log4jLoggerLogbackLogger 是两种不同的日志实现。通过 Log4jAdapterLogbackAdapter,我们可以将这两个日志框架适配为统一的 Logger 接口,方便调用者在不关心底层实现的情况下进行日志记录。

总结

适配器模式的核心优势在于能够将不同接口之间的兼容性问题转化为更易处理的形式。通过上述四个场景的详细示例,我们可以看到适配器模式在开发中的广泛应用。不论是统一多个类的接口设计、替换外部系统、兼容老旧接口还是处理不同数据格式,适配器模式都能有效提高代码的灵活性与可维护性。希望这篇博客能够帮助你更好地理解适配器模式的应用!

相关文章:

适配器模式适用的场景

适配器模式是一种常用的设计模式,能够将不兼容的接口转换为客户端所需的接口。在实际开发中,我们常常会遇到需要统一接口、替换外部系统、兼容旧接口或适配不同数据格式的情况。本文将结合详细的代码示例,介绍适配器模式的适用场景。 1. 统一…...

Ambari里面添加hive组件

1.创建hive数据库 在添加hive组件之前需要做的事情,先在master这个虚拟机里面创建好hive 先进入虚拟机里面进入mysql 然后输入这个命令看看有没有自己创建的hive数据库 show databases;有的话会显示下面这个样子 没有的同学使用以下命令可以在MySQL中创建hive数…...

Windows部署rabbitmq

本次安装环境: 系统:Windows 11 软件建议版本: erlang OPT 26.0.2rabbitmq 3.12.4 一、下载 1.1 下载erlang 官网下载地址: 1.2 下载rabbitmq 官网下载地址: 建议使用解压版,安装版可能会在安装软件…...

【Flask】四、flask连接并操作数据库

目录 前言 一、 安装必要的库 二、配置数据库连接 三、定义模型 四、操作数据库 1.添加用户 2.删除用户 3.更新用户信息 4查询所有用户 五、测试结果 前言 在Flask框架中,数据库的操作是一个核心功能,它允许开发者与后端数据库进行交互&#xf…...

ES跟Kafka集成

配合流程 1. Kafka作为分布式流处理平台,能够实时收集和处理不同数据源的数据流; 2. 通过Kafka Connect或者Logstash等中间件,可以将Kafka中的数据流实时推送到Elasticsearch中; 3. Elasticsearch接收到数据后,会根据…...

Python Matplotlib:基本图表绘制指南

Python Matplotlib:基本图表绘制指南 Matplotlib 是 Python 中一个非常流行的绘图库,它以简单易用和功能丰富而闻名,适合各种场景的数据可视化需求。在数据分析和数据科学领域,Matplotlib 是我们展示数据的有力工具。本文将详细讲…...

供应商图纸外发:如何做到既安全又高效?

供应商跟合作伙伴、客户之间会涉及到图纸外发的场景,这是一个涉及数据安全、效率及合规性的重要环节。供应商图纸发送流程一般如下: 1.申请与审批 采购人员根据需要提出发放图纸的申请并提交审批; 采购部负责人审批发放申请,确…...

探索 Move 编程语言:智能合约开发的新纪元

目录 引言 一、变量的定义 二、整型 如何在Move中表示小数和负数? 三、运算符 as运算符 布尔型 地址类型 四、什么是包? 五、什么是模块? 六、如何定义方法? 方法访问权限控制 init方法 总结 引言 Move 是一种专为区…...

vue3+vant实现视频播放(含首次禁止进度条拖拽,视频看完后恢复,保存播放视频进度,刷新及下次进入继续播放,判断视频有无全部看完等)

1、效果图 2、 <div><videocontrolsclass"video_player"ref"videoPlayer":src"videoSrc"timeupdate"handleTimeUpdate"play"onPlay"pause"onPause"ended"onVideoEnded"></video><…...

情感强度分析:精确衡量文本情感强弱的 AI 技术

情感强度分析&#xff1a;精确衡量文本情感强弱的 AI 技术 一、引言 在当今信息爆炸的时代&#xff0c;我们每天都会接触到大量的文本信息。这些文本中蕴含着各种各样的情感&#xff0c;如喜悦、悲伤、愤怒、恐惧等。如何准确地理解和分析这些文本的情感强度&#xff0c;对于…...

工厂方法模式与抽象工厂模式

工厂方法模式 (Factory Method) 定义&#xff1a; 工厂方法模式是一种创建型设计模式&#xff0c;它定义了一个用于创建对象的接口&#xff0c;但让子类决定实例化哪个类。工厂方法将类的实例化推迟到子类。 优点&#xff1a; 解耦&#xff1a;客户端代码与具体的产品类解耦…...

「Math」初等数学知识点大纲(占位待处理)

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...

百元高性价比头戴式降噪耳机选哪款?四款平价性价比品牌别错过!

随着科技的发展&#xff0c;现在的头戴式耳机真的是越来越多样了&#xff0c;很多的朋友在选购耳机的时候&#xff0c;不知道哪一款头戴式耳机的性价比较高&#xff0c;究竟百元高性价比头戴式降噪耳机选哪款&#xff1f;身为一名数码爱好者&#xff0c;这里就给大家推带来四款…...

vue3 setup写不写到标签上的区别

在vue3种setup的写法&#xff0c;可以单独写setup()也可以写到script标签中&#xff0c;当然我们推荐后面这种 他的好处有很多&#xff0c;代码也简洁很多。1、属性和方法无需return&#xff0c;可直接使用 /*原先*/ <script> import { defineComponent } from "v…...

【论文解读】EdgeYOLO:一种边缘实时目标检测器(附论文地址)

论文地址&#xff1a;https://arxiv.org/pdf/2302.07483 这篇文章的标题是《EdgeYOLO: An Edge-Real-Time Object Detector》&#xff0c;由中国北京理工大学的Shihan Liu、Junlin Zha、Jian Sun、Zhuo Li和Gang Wang共同撰写。这篇论文提出了一个基于最新YOLO框架的高效、低复…...

xlwings,让excel飞起来!

excel已经成为必不可少的数据处理软件&#xff0c;几乎天天在用。python有很多支持操作excel的第三方库&#xff0c;xlwings是其中一个。 关于xlwings xlwings开源免费&#xff0c;能够非常方便的读写Excel文件中的数据&#xff0c;并且能够进行单元格格式的修改。 xlwings还…...

C语言学习,标准库 <stddef.h>

<stddef.h> C 标准库中头文件&#xff0c;它定义了一些常用的类型定义和宏。这些定义通常用于指针操作、数组处理和其他需要固定大小数据类型的场合。 size_t&#xff1a; 这是一个无符号整数类型&#xff0c;用于表示对象的大小&#xff08;以字节为单位&#xff09;。…...

PyQt5实战——操作台打印重定向,主界面以及stacklayout使用(四)

个人博客&#xff1a;苏三有春的博客 系类往期文章&#xff1a; PyQt5实战——多脚本集合包&#xff0c;前言与环境配置&#xff08;一&#xff09; PyQt5实战——多脚本集合包&#xff0c;UI以及工程布局&#xff08;二&#xff09; PyQt5实战——多脚本集合包&#xff0c;程序…...

React + Vite + TypeScript + React router项目搭建教程

一、创建项目 运行项目 二、目录结构 项目目录&#xff1a; ├─node_modules //第三方依赖 ├─public //静态资源&#xff08;不参与打包&#xff09; └─src├─assets //静态资源├─components //组件├─config //配置├─http //请求方法封装├─layout //页面…...

【ShuQiHere】️ 如何启用 SSH 服务

&#x1f6e0;️ 如何启用 SSH 服务 目录 基础概念 &#x1f331;检查是否已安装 SSH 服务 &#x1f50d;在不同操作系统上安装 SSH 服务 &#x1f4bb; LinuxWindows 11macOS 启动和启用 SSH 服务 &#x1f680;配置防火墙以允许 SSH 连接 &#x1f525;配置 SSH 服务&#…...

慢慢欣赏linux 之 last = switch_to(prev, next)分析

last switch_to(prev, next); 为什么需要定义last作为调用switch_to之前的prev的引用 原因如下&#xff1a; struct task_struct * switch_to(struct task_struct *prev,struct task_struct *next) {... ...return cpu_switch_to(prev, next);> .global cpu_switch_tocpu_…...

【Zephyr 系列 14】使用 MCUboot 实现 BLE OTA 升级机制:构建安全可靠的固件分发系统

🧠关键词:Zephyr、MCUboot、OTA 升级、BLE DFU、双分区、Bootloader、安全固件管理 📌面向读者:希望基于 Zephyr 为 BLE 设备加入安全 OTA 升级功能的开发者 📊预计字数:5200+ 字 🧭 前言:为什么你需要 OTA? 随着设备部署数量增多与产品生命周期延长,远程升级(…...

Python学习(7) ----- Python起源

&#x1f40d;《Python 的诞生》&#xff1a;一段圣诞假期的奇妙冒险 &#x1f4cd;时间&#xff1a;1989 年圣诞节 在荷兰阿姆斯特丹的一个寒冷冬夜&#xff0c;灯光昏黄、窗外飘着雪。一个程序员 Guido van Rossum 正窝在家里度假——没有会议、没有项目、没有 bug&#xf…...

模拟搭建私网访问外网、外网访问服务器服务的实践操作

目录 实验环境 实践要求 一、准备工作 1、准备四台虚拟机&#xff0c;分别标号 2、 防火墙额外添加两块网卡&#xff0c;自定义网络连接模式 3、 关闭虚拟机的图形管理工具 4、关闭防火墙 5、分别配置四台虚拟机的IP地址&#xff0c;此处举一个例子&#xff08;使用的临…...

CoordConv: CNN坐标感知特征适应

传统卷积 vs CoordConv 详细对比 传统卷积对空间位置不敏感&#xff0c;CoordConv通过显式添加坐标信息解决这个问题在特征图中嵌入(x, y)坐标和可选的径向距离r使模型能够感知空间位置关系 1. 传统卷积的"空间位置不敏感"问题 传统卷积的特点&#xff1a; 输入: …...

STM32什么是寄存器

提示&#xff1a;文章 文章目录 前言一、背景二、2.12.2 三、3.1 总结 前言 前期疑问&#xff1a; 1、什么是寄存器&#xff1f; 答&#xff1a;在4GB的地址空间中&#xff0c;512MB的block2上&#xff0c;每4个字节组成32位&#xff0c;这个32位为一个单元&#xff0c;控制&a…...

Design Theory and Method of Complex Products: A Review

abstract 摘要 Design is a high-level and complex thinking activity of human beings, using existing knowledge and technology to solve problems and create new things. With the rise and development of intelligent manufacturing, design has increasingly reflec…...

数据库学习(二)——MySQL语句

MySQL 语句分为&#xff1a; 语句类型作用关键字示例数据查询&#xff08;DQL&#xff09;查询数据SELECT数据操作&#xff08;DML&#xff09;插入、更新、删除数据INSERT, UPDATE, DELETE数据定义&#xff08;DDL&#xff09;定义或修改表结构CREATE, ALTER, DROP事务控制&a…...

提取数据区域中表格

查看本示例演示效果本示例关键代码的编写位置&#xff0c;请参考“开始 - 快速上手”里您所使用的开发语言框架的最简集成代码 在实际的开发过程中&#xff0c;有时会遇到希望提取Word文档中表格数据保存到服务器的需求&#xff0c;此时可以使用PageOffice提取Word文档数据区域…...

随访系统安装的记录

安装PG17.5 安装https://www.cnblogs.com/nulixuexipython/p/18040243 1、遇到navicat链接不了PG https://blog.csdn.net/sarsscofy/article/details/84985933 2、查看有无安装mysqlhttps://blog.51cto.com/u_16175430/7261412 3、 方案一&#xff1a;oracle不开日志 data…...