go设计模式———适配器模式

适配器模式是一种设计模式,用来解决接口不兼容的问题。它的作用是让原本因为接口不兼容而无法一起工作的类能够协同工作。通俗地说,它就像是一种“转换器”,能够把一种接口转化为另一种接口,从而让不同的系统或组件可以一起使用。

通俗解释

想象一下你在国外旅行,发现你的手机充电器只能插在中国的插座上(两脚扁插头),但你现在在欧洲,而欧洲的插座是圆孔的。这个时候,你需要一个电源适配器,把你的充电器插头转换成能插进欧洲插座的形状,这样你才能给手机充电。适配器就是那个中间转换的工具。

在编程中,适配器模式的作用就类似于这种电源适配器。当两个类的接口不兼容时,适配器模式通过引入一个中间类(适配器),让这两个类能够一起工作。

适配器模式解决的问题

适配器模式主要解决的是“如何让两个不兼容的类或者接口能够协同工作”。通常,这两个类之间存在一定的关联性,但由于接口不同,不能直接一起使用。适配器模式通过将一个类的接口转化为客户端期望的接口,让不兼容的类能够在一起使用而无需修改它们的原始代码。

使用场景

•	集成遗留系统:当你需要将新系统集成到旧系统中,但新旧系统的接口不兼容时,可以使用适配器模式。
•	第三方库兼容:当你想要使用一个第三方库,但它的接口与你的系统接口不兼容时,适配器可以帮助你桥接这两个接口。
•	接口标准化:在开发中,当你需要统一不同的接口形式时,可以通过适配器模式将各种不同的接口转换为统一的形式。

下面是一个使用适配器模式的 Go 语言代码示例,通过电源适配器的比喻来展示如何在编程中使用适配器模式,将不兼容的接口连接起来。

示例场景

假设我们有一个中国的插头(两脚扁插头)和一个欧洲的插座(圆孔插座)。我们的中国插头(ChinaPlug)只能插在中国的插座上(ChinaSocket),而我们的欧洲插座(EuroSocket)只能接受圆孔的插头。我们需要通过一个适配器(PlugAdapter)将中国插头适配到欧洲插座上。

1. 定义中国插头和插座接口

package mainimport "fmt"// ChinaPlug 是中国插头的接口
type ChinaPlug interface {InsertChinaPlug() string
}// ChinaSocket 是中国插座的接口
type ChinaSocket interface {PlugIn(plug ChinaPlug) string
}

2. 实现中国插头和插座

// ChinesePlug 是一个实现了 ChinaPlug 接口的具体类
type ChinesePlug struct{}func (p *ChinesePlug) InsertChinaPlug() string {return "中国插头插入中国插座"
}// ChineseSocket 是一个实现了 ChinaSocket 接口的具体类
type ChineseSocket struct{}func (s *ChineseSocket) PlugIn(plug ChinaPlug) string {return plug.InsertChinaPlug()
}

3. 定义欧洲插座接口

// EuroSocket 是欧洲插座的接口
type EuroSocket interface {PlugInEuroSocket() string
}

4. 实现欧洲插座

// EuropeanSocket 是一个实现了 EuroSocket 接口的具体类
type EuropeanSocket struct{}func (s *EuropeanSocket) PlugInEuroSocket() string {return "欧洲插座准备接收插头"
}

5. 创建适配器 PlugAdapter,适配中国插头到欧洲插座

// PlugAdapter 是适配器类,适配中国插头到欧洲插座
type PlugAdapter struct {chinesePlug ChinaPlug
}func (a *PlugAdapter) PlugInEuroSocket() string {return a.chinesePlug.InsertChinaPlug() + " 通过适配器接入欧洲插座"
}

6. 使用适配器将中国插头插入欧洲插座

func main() {// 创建一个中国插头chinaPlug := &ChinesePlug{}// 创建一个欧洲插座euroSocket := &EuropeanSocket{}// 使用适配器将中国插头适配到欧洲插座adapter := &PlugAdapter{chinesePlug: chinaPlug}// 插入欧洲插座fmt.Println(euroSocket.PlugInEuroSocket())fmt.Println(adapter.PlugInEuroSocket())
}

7. 运行结果

当你运行这段代码时,输出将会是:

欧洲插座准备接收插头
中国插头插入中国插座 通过适配器接入欧洲插座

代码解析

  • ChinaPlug 和 ChinaSocket:定义了中国插头和插座的接口和实现。
  • EuroSocket:定义了欧洲插座的接口和实现。
  • PlugAdapter:适配器类,实现了 EuroSocket 接口,并在内部持有一个 ChinaPlug 对象。在 PlugInEuroSocket 方法中,它调用了 ChinaPlugInsertChinaPlug 方法,同时通过适配器将其适配到欧洲插座的接口。
  • main 函数:演示了如何使用适配器模式将中国插头适配到欧洲插座上。

这个示例展示了适配器模式的实际应用场景,通过引入适配器类,成功让不兼容的接口协同工作。

package adapterimport "fmt"// ApplePlug 苹果手机充电插槽
type ApplePlug interface {ConnectLightning() string
}// IPhone 苹果系列手机
type IPhone struct {model string
}// NewIPhone 苹果手机创建方法
func NewIPhone(model string) *IPhone {return &IPhone{model: model,}
}// ConnectLightning 苹果手机Lightning充电插槽
func (i *IPhone) ConnectLightning() string {return fmt.Sprintf("%v connect lightning plug", i.model)
}// CommonPlug 通用的USB电源插槽
type CommonPlug interface {ConnectUSB() string
}// ApplePhonePlugAdapter 苹果Lightning充电插槽适配通用USB充电插槽
type ApplePhonePlugAdapter struct {iPhone ApplePlug
}// NewApplePhonePlugAdapter 创建苹果手机适配USB充电插槽适配器
func NewApplePhonePlugAdapter(iPhone ApplePlug) *ApplePhonePlugAdapter {return &ApplePhonePlugAdapter{iPhone: iPhone,}
}// ConnectUSB 链接USB
func (a *ApplePhonePlugAdapter) ConnectUSB() string {return fmt.Sprintf("%v adapt to usb ", a.iPhone.ConnectLightning())
}// PowerBank 充电宝
type PowerBank struct {brand string
}// Charge 支持通用USB接口充电
func (p *PowerBank) Charge(plug CommonPlug) string {return fmt.Sprintf("%v power bank connect usb plug, start charge for %v", p.brand, plug.ConnectUSB())
}

代码解析

1.	ApplePlug 接口:定义了苹果手机的 Lightning 插槽。
2.	IPhone 类:实现了 ApplePlug 接口,代表苹果手机。
3.	CommonPlug 接口:定义了充电宝支持的通用 USB 接口。
4.	ApplePhonePlugAdapter 类:适配器类,将苹果手机的 Lightning 插槽适配为充电宝的通用 USB 插槽。
5.	PowerBank 类:代表充电宝,支持通用 USB 接口的充电。
6.	TestAdapter 测试函数:展示了如何通过适配器将苹果手机连接到充电宝。

这个例子展示了如何使用适配器模式解决不同接口设备之间的兼容性问题,让旧接口设备也能与新接口设备一起工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/51081.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

联合体成员的访问——真题讲解

【题目】 阅读下述代码,请问修改data的value成员以存储3.14,正确的方式是() union Data { int num; float value; char symbol; }; union Data data; A. data.value 3.14; B. value.data 3.14; C. data->value 3.14; D. value->data 3.1…

Java学习_18_Stream流

文章目录 前言一、不可变集合二、Stream流思想第一步:得到Stream流第二步:Stream流的中间方法Stream流的终结方法 总结 前言 博客仅记录个人学习进度和一些查缺补漏。 学习内容:BV17F411T7Ao 一、不可变集合 不可变集合就是长度和内容都不可…

希尔排序,详细解析(附图解)

1.希尔排序思路 希尔排序是一种基于插入排序的算法,通过将原始数据分成若干个子序列,然后对子序列进行插入排序,逐渐减小子序列的间隔,最后对整个序列进行一次插入排序。 1.分组直接插入排序,目标接近有序--------…

transformers调用llama的方式

transformers调用llama的使用方式 不同版本llama对应的transformers库版本llama2llama3Meta-Llama-3-8B-InstructMeta-Llama-3-8B llama3.1Meta-Llama-3.1-8B-Instruct 不同版本llama对应的transformers库版本 # llama2 pip install torch1.13.1cu116 torchvision0.14.1cu116 …

C语言贪吃蛇之BUG满天飞

C语言贪吃蛇之BUG满天飞 今天无意间翻到了大一用C语言写的贪吃蛇&#xff0c;竟然还标注着BUG满天飞&#xff0c;留存一下做个纪念&#xff0c;可能以后就找不到了 /* 此程序 --> 贪吃蛇3.0 Sur_流沐 当前版本&#xff1a; Bug满天飞 */ #include<stdio.h> #includ…

【补充篇】AUTOSAR多核OS介绍(下)

文章目录 前文回顾1 AUTOSAR OS1.1 AUTSOAR OS元素1.1.1 操作系统对象1.1.2 操作系统应用程序1.1.3 AUTOSAR OS裁剪类型1.1.4 AUTOSAR OS软件分区1.2 AUTOSAR OS自旋锁1.3 AUTOSAR OS核间通信1.4 AUTOSAR OS多核调度前文回顾 在上篇文章【补充篇】AUTOSAR多核OS介绍(上)中,…

docker常见指令——镜像指令and容器指令

docker镜像指令 查看镜像 docker images 搜索镜像 docker search 镜像名 上传镜像 docker pull 镜像名 或 docker pull 镜像名&#xff1a;tag 注:不加:tag表示最新版本 &#xff0c;加:tag表示指定版本 运行镜像 docker run 镜像名 保存镜像 docker save 镜像名/镜像id -o 要…

OpenMax算法详解:深度学习中的高效开集识别技术

OpenMax算法详解&#xff1a;深度学习中的高效开集识别技术 在深度学习领域&#xff0c;模型的识别能力往往受限于其训练数据集的范畴。传统的分类模型&#xff0c;如卷积神经网络&#xff08;CNN&#xff09;或循环神经网络&#xff08;RNN&#xff09;&#xff0c;通常被设计…

算法5:位运算

文章目录 小试牛刀进入正题 没写代码的题&#xff0c;其链接点开都是有代码的。开始前请思考下图&#xff1a; 小试牛刀 位1的个数 class Solution { public:int hammingWeight(int n) {int res 0;while (n) {n & n - 1;res;}return res;} };比特位计数 class Solution…

关于我的生信笔记开通《知识星球》

关于知识星球 1. 为什么到现在才开通《知识星球》 从很早关注我的同学应该了解小杜的知识分享历程&#xff0c;小杜是从2021年11月底开始进入此“坑”&#xff0c;一直坚持到现在&#xff0c;马上3年了&#xff08;24年11月底到期&#xff09;。自己也从一个小青年&#xff0…

什么是网页爬虫技术

网页爬虫技术&#xff08;Web Crawler Technology&#xff09;是一种自动化浏览互联网并收集信息的程序或脚本。这些程序模拟人类用户的行为&#xff0c;通过HTTP请求访问网页&#xff0c;并解析网页内容&#xff08;通常是HTML文档&#xff09;&#xff0c;从中提取出所需的数…

hostapd生成beacon_ie

配置文件 /data/vendor/wifi/hostapd/hostapd_wlan0.conf 配置参数 AP启动过程&#xff1a;1.上层配置一些参数并根据参数生成配置文件 2.init的时候设置默认参数并加载配置文件上的参数&#xff08;如果重复&#xff0c;以配置文件上的设置优先&#xff09; 相关函数及结构…

查看U盘的具体信息,分区表格式、实际容量和分区状态

查看U盘的具体信息&#xff0c;分区表格式、实际容量和分区状态 前言&#xff1a; 利用windows自带的命令行窗口就可以 1、使用命令提示符查看MBR和GPT分区类型 &#xff08;1&#xff09;按“Windows R”键&#xff0c;在弹出的运行对话框中输入“diskpart”&#xff0c;并按…

electron 中 webPreferences 作用

webPreferences 是 BrowserWindow 构造函数中的一个选项对象&#xff0c;用于配置网页的相关偏好设置。 它包含了一系列的属性&#xff0c;用于控制网页在 Electron 窗口中的行为和功能&#xff1a; 1. nodeIntegration&#xff1a;决定是否在渲染进程中启用 Node.js 的集成。…

代码随想录算法训练营第五十五天 | 并查集理论基础、107. 寻找存在的路径

一、并查集理论基础 文章链接&#xff1a;并查集理论基础 | 代码随想录 (programmercarl.com) 二、107. 寻找存在的路径 题目连接&#xff1a;107. 寻找存在的路径 (kamacoder.com) 文章讲解&#xff1a;代码随想录 (programmercarl.com)——107. 寻找存在的路径

redis面试(十九)读写锁ReadLock

读写锁ReadLock 简单来说就是互斥锁和非互斥锁。多个客户端可以同事加的锁叫读锁&#xff0c;只能有一个客户端加的锁叫写锁。这个理论应该是从数据库中来的&#xff0c;放在这里也是同样的解释。 多个客户端同时加读锁&#xff0c;是不会互斥的&#xff0c;多个客户端可以同…

@Param注解的踩坑,报错:There is no getter for property named ‘dto‘ in ‘class

哈喽&#xff0c;大家好&#xff0c;我今天又来记录一下鄙人做后端开发的后知后觉&#xff1a; Param注解&#xff0c;相信大家都不陌生吧&#xff0c;Param 注解用于在 Mapper 接口的方法上明确指定参数的名称&#xff0c;比如如下&#xff1a; List<oucherOrderVO> li…

YOLOv8_det/seg/pose/obb推理流程

本章将介绍目标检测、实例分割、关键点检测和旋转目标检测的推理原理,基于onnx模型推理,那么首先就需要了解onnx模型的输入和输出,对输入的图片需要进行预处理的操作,对输出的结果需要进行后处理的操作,这部分内容在我的另一个专栏《YOLOv8深度剖析》中也有介绍,如果对YO…

【Leetcode 1512 】 好数对的数目—— 数组模拟哈希表 与 等差数列求和

给你一个整数数组 nums 。 如果一组数字 (i,j) 满足 nums[i] nums[j] 且 i < j &#xff0c;就可以认为这是一组 好数对 。 返回好数对的数目。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3,1,1,3] 输出&#xff1a;4 解释&#xff1a;有 4 组好数对&#xff0c;…

canal数据同步工具介绍与应用

canal服务 canal介绍canal版本与环境canal 服务集canal应用场景&#xff1a; canal常见问题xml配置问题连接认证问题jar版本问题连接问题 canal介绍 ‌1、Canal是‌阿里巴巴开源的‌MySQL增量数据订阅和消费工具&#xff0c;通过模拟MySQL的‌slave与‌master交互&#xff0c;捕…