适配器模式——C++实现
目录
1. 适配器模式简介
2. 角色组成
3. 代码示例
4. 适配器模式、装饰器模式、外观模式的辨析
1. 适配器模式简介
适配器模式是一种结构型模式。
适配器模式的定义:适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不可兼容的类可以合作无间。
简而言之,适配器模式可以将一种接口转换成我们想要的形式。
举个例子,家用插座的供电时220V交流电,而普通手机的充电口需要的是5V的直流电。它们俩的接口不同,所以不可以通过导线直接连接起来给手机充电。
我们平时使用的手机充电器它的正式名称是电源适配器,电源适配器通过一系列的转换,将220V交流电转换成手机所需要的5V直流电。
手机的充电器就是一种典型的适配器:把一种接口转换成另一种我们需要的接口。
2. 角色组成
- 被适配者:需要被适配的不兼容的对象(比如220V交流电的插座)
- 适配器:充当了接口之间的中间转换角色,将被适配者的接口转换成目标接口(比如手机的电源适配器,将220V交流电的插座转换成5V直流电)
- 目标接口:需要适配的标准接口(我们所需要的目标接口,比如5V直流电接口)
3. 代码示例
有一个鸭子模拟程序,有一个鸭子接口,还有一个火鸡接口,两个接口不同。如果有一个火鸡类,我们想把火鸡类当作鸭子类型使用,但是接口不同,这时候就可以通过适配器模式进行接口转换。
详情请见以下代码:
#if 1#include <iostream>using namespace std;class Duck
{
public:virtual ~Duck() {}virtual void quack() = 0;virtual void fly() = 0;
};class Turkey
{
public:virtual ~Turkey() {}virtual void gobble() = 0;virtual void fly() = 0;
};class MallardDuck : public Duck
{
public:void quack() override{cout << "嘎嘎嘎" << endl;}void fly() override{cout << "我正在飞翔" << endl;}
};class WildTurkey : public Turkey
{
public:void gobble() override{cout << "咕咕咕" << endl;}void fly() override{cout << "我正在飞翔,但我飞行距离很短" << endl;}
};class TurkeyAdapter : public Duck
{
public:TurkeyAdapter(Turkey* turkey) : m_turkey(turkey) {}void quack() override{m_turkey->gobble();}void fly() override{for (int i = 0; i < 5; i++){m_turkey->fly();}}private:Turkey* m_turkey;
};void testDuck(Duck* duck)
{duck->quack();duck->fly();
}int main()
{Duck* duck = new MallardDuck();Turkey* turkey = new WildTurkey();Duck* turkeyAdapter = new TurkeyAdapter(turkey);testDuck(duck);cout << "-------------------------" << endl;testDuck(turkeyAdapter);delete duck;delete turkeyAdapter;delete turkey;return 0;}
#endif
通过火鸡适配器,就可以让火鸡来冒充鸭子类型,即便它们的接口并不一样。
4. 适配器模式、装饰器模式、外观模式的辨析
- 装饰器模式:装饰器和适配器模式一样,都是用来包装对象的。装饰器对象可以为context对象增加新的行为和红能,但装饰器对象不会改变原有的接口。
- 适配器模式:适配器模式也会包装对象(包装被适配对象),适配器模式会对调用context对象的接口并作出适当的改变来适应新接口。适配器模式一定会改变原有的接口,继承新接口并包装老接口来实现接口的转换。适配器模式不会增加新的功能,但是一定会进行接口的转换。
- 外观模式:外观模式和适配器模式一样,也会改变接口,但是外观模式改变接口是为了简化接口。外观模式将多个类背后的复杂调用隐藏起来,只暴露出几个干净美好的简单接口给客户端代码。外观模式可以简化客户端代码对复杂子系统的使用过程,客户端无需了解复杂子系统的即可使用,符合最少知识原则。
相关文章:
适配器模式——C++实现
目录 1. 适配器模式简介 2. 角色组成 3. 代码示例 4. 适配器模式、装饰器模式、外观模式的辨析 1. 适配器模式简介 适配器模式是一种结构型模式。 适配器模式的定义:适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不可兼容…...
搭建Spark分布式集群
1,下载 下载 spark-3.5.4-bin-without-hadoop.tgz 地址: https://downloads.apache.org/spark/spark-3.5.4/ 2,安装 通过虚拟机设置共享文件夹将需要的安装包复制到linux虚拟机中 localhost1。虚拟机的共享盘在 /mnt/hgfs/。 将共享盘安装…...
doris:STRUCT
STRUCT<field_name:field_type [COMMENT comment_string], ... > 表示由多个 Field 组成的结构体,也可被理解为多个列的集合。 不能作为 Key 使用,目前 STRUCT 仅支持在 Duplicate 模型的表中使用。一个 Struct 中的 Field 的名字和数量固定&…...
【Java基础-41.5】深入解析Java异常链:构建清晰的错误追踪体系
在Java编程中,异常处理是保证程序健壮性和可维护性的重要部分。然而,在实际开发中,异常往往不是孤立发生的,而是由一系列相关的异常引发的。为了更好地理解和处理这种复杂的异常场景,Java引入了 异常链(Exc…...
新年祝词(原创)
新年将至,福进万户。 家家团圆,事事顺心。 喜迎财神,多寿添金。 瑞兽迎春,炮竹声起。 趋吉避凶,蛇年大吉。 中华崛起,人人自强。 天下大同,百姓富足。 有情有义,平易近人。 …...
线上突发:MySQL 自增 ID 用完,怎么办?
线上突发:MySQL 自增 ID 用完,怎么办? 1. 问题背景2. 场景复现3. 自增id用完怎么办?4. 总结 1. 问题背景 最近,我们在数据库巡检的时候发现了一个问题:线上的地址表自增主键用的是int类型。随着业务越做越…...
ESP32 I2S音频总线学习笔记(二):I2S读取INMP441音频数据
简介 在这个系列的上一篇文章中,我们介绍了ESP32 I2S音频总线的相关知识,简要了解了什么是I2S总线、它的通信格式,以及相关的底层API函数。没有看过上篇文章的可以点击文章进行回顾: ESP32 I2S音频总线学习笔记(一&a…...
一文简单回顾Java中的String、StringBuilder、StringBuffer
简单说下String、StringBuilder、StringBuffer的区别 String、StringBuffer、StringBuilder在Java中都是用于处理字符串的,它们之间的区别是String是不可变的,平常开发用的最多,当遇到大量字符串连接的时候,就用StringBuilder&am…...
matlab中,fill命令用法
在 MATLAB 中,fill 命令用于创建填充多边形的图形对象。使用 fill 可以在二维坐标系中绘制填充的区域,通常用于绘制图形的背景或显示数据分布。 基本语法 fill(X, Y, C)X 和 Y 是同样长度的向量,定义了多边形的顶点坐标。C 是颜色࿰…...
深入解析 Linux 内核内存管理核心:mm/memory.c
在 Linux 内核的众多组件中,内存管理模块是系统性能和稳定性的关键。mm/memory.c 文件作为内存管理的核心实现,承载着页面故障处理、页面表管理、内存区域映射与取消映射等重要功能。本文将深入探讨 mm/memory.c 的设计思想、关键机制以及其在内核中的作用,帮助读者更好地理…...
Ubuntu 16.04安装Lua
个人博客地址:Ubuntu 16.04安装Lua | 一张假钞的真实世界 在Linux系统上使用以下命令编译安装Lua: curl -R -O http://www.lua.org/ftp/lua-5.3.3.tar.gz tar zxf lua-5.3.3.tar.gz cd lua-5.3.3 make linux test 安装make 编译过程如果提示以下信息…...
vue中的el是指什么
简介: 在Vue.js中,el指的是Vue实例的挂载元素。 具体来说,el是一个选项,用于指定Vue实例应该挂载到哪个DOM元素上。通过这个选项,Vue可以知道应该从哪个元素开始进行模板编译和渲染。它可以是一个CSS选择器字符串&…...
计算机网络之链路层
本文章目录结构出自于《王道计算机考研 计算机网络_哔哩哔哩_bilibili》 02 数据链路层 在网上看到其他人做了详细的笔记,就不再多余写了,直接参考着学习吧。 1 详解数据链路层-数据链路层的功能【王道计算机网络笔记】_wx63088f6683f8f的技术博客_51C…...
Vue 3 30天精进之旅:Day 07 - Vue Router
引言 在前几天的学习中,我们深入探讨了Vue的表单输入绑定及其处理机制。今天,我们将学习Vue Router,这是Vue.js官方提供的路由管理器,用于构建单页面应用(SPA)。通过使用Vue Router,你可以轻松…...
lib.exe正确用法winhv.lib生成方法
lib.exe /def:winhv.def /OUT:winhv.lib /machine:x64 winhv.def注意是 winhv.sys要不然会变成dll LIBRARY winhv.sys EXPORTSWinHvAllocateOverlayPagesWinHvDisablePartitionVtlWinHvDisableVpVtlWinHvEnablePartitionVtlWinHvEnableVpVtlWinHvFreeOverlayPagesWinHvGetCurr…...
react-bn-面试
1.主要内容 工作台待办 实现思路: 1,待办list由后端返回,固定需要的字段有id(查详细)、type(本条待办的类型),还可能需要时间,状态等 2,一个集中处理待办中转路由页,所有待办都跳转到这个页面…...
Spring Boot Actuator 集成 Micrometer(官网文档解读)
目录 概述 实现 Observation 可观测性 Observation 功能核心类 ObservationPredicate GlobalObservationConvention ObservationFilter ObservationHandler ObservationRegistryCustomizer Observation 相关注解 多线程处理机制 配置上下文传播 常用标签配置 Open…...
Kotlin函数式API
Kotlin函数式API 1.maxBy val list listOf("Apple","Banana", "Orange","pear","Grape","Watermelon") val maxLengthFruit list.maxBy {it.length} println(maxLengthFruit) 2.map 集合中zhi的map函数是最…...
Linux:一切皆文件
**文件描述符**:它是一种特殊的索引,本质上是进程中file_struct结构体成员fd_array数组的下标。在Linux等系统中,文件描述符是一个非负整数,用于标识打开的文件,是内核为了高效管理已被打开的文件所创建的索引。通过文…...
【物联网】ARM核常用指令(详解):数据传送、计算、位运算、比较、跳转、内存访问、CPSR/SPSR、流水线及伪指令
文章目录 指令格式(重点)1. 立即数2. 寄存器位移 一、数据传送指令1. MOV指令2. MVN指令3. LDR指令 二、数据计算指令1. ADD指令1. SUB指令1. MUL指令 三、位运算指令1. AND指令2. ORR指令3. EOR指令4. BIC指令 四、比较指令五、跳转指令1. B/BL指令2. l…...
项目集成Nacos
文章目录 1.环境搭建1.创建模块 sunrays-common-cloud-nacos-starter2.目录结构3.pom.xml4.自动配置1.NacosAutoConfiguration.java2.spring.factories 5.引入cloud模块通用依赖 2.测试1.创建模块 sunrays-common-cloud-nacos-starter-demo2.目录结构3.pom.xml4.application.ym…...
QT交叉编译环境搭建(Cmake和qmake)
介绍一共有两种方法(基于qmake和cmake): 1.直接调用虚拟机中的交叉编译工具编译 2.在QT中新建编译套件kits camke和qmake的区别:CMake 和 qmake 都是自动化构建工具,用于简化构建过程,管理编译设置&…...
【某大厂一面】数组和链表区别
在 Java 中,数组(Array)和链表(LinkedList)是两种常见的数据结构,它们在存储和操作方式上有显著的区别。了解它们的差异有助于选择适合特定应用场景的结构。下面是数组和链表之间的详细比较。 1. 存储结构…...
基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结
title: 基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结 tags: - jenkins - python categories: - jenkins在软件开发的持续集成与持续交付(CI/CD)流程里,及时、准确地获取并分析测试报告对保障软件质量至关重要。本文将详细…...
一文大白话讲清楚webpack进阶——5——dev-server原理及其作用
文章目录 一文大白话讲清楚webpack进阶——5——dev-server原理及其作用1. webpack的作用2. dev-server的作用3. dev-server的原理3.1 啥是webpack-dev-middleware3.2 HMR 一文大白话讲清楚webpack进阶——5——dev-server原理及其作用 1. webpack的作用 webpack的作用我们之…...
[cg] 使用snapgragon 对UE5.3抓帧
最近想要抓opengl 的api,renderdoc在起应用时会闪退(具体原因还不知道),试了下snapgraon, 还是可以的 官网需要注册登录后下载,官网路径:Developer | Qualcomm 为了方便贴上已经下载好的exe安装包&#x…...
Java学习教程,从入门到精通,JDBC插入记录语法及案例(104)
JDBC插入记录语法及案例 一、JDBC插入记录语法 在JDBC中,插入记录主要通过执行SQL的INSERT语句来实现。其基本语法如下: INSERT INTO 表名 (列1, 列2, ..., 列n) VALUES (值1, 值2, ..., 值n);表名:需要插入记录的表的名称。列1, 列2, …,…...
物业巡更系统在现代社区管理中的优势与应用探讨
内容概要 在现代社区管理中,物业巡更系统正逐渐成为一种不可或缺的工具。结合先进的智能技术,这些系统能够有效地提升社区管理的各个方面,尤其是在巡检效率和信息透明度方面。通过实时记录巡检数据,物业管理人员能够确保工作人员…...
速通Docker === Docker Compose
目录 Docker Compose 简介 Docker Compose 常用命令 使用 Docker Compose 启动 WordPress 普通启动方式(使用 Docker 命令) 使用 Docker Compose 启动 Docker Compose 的特性 Docker Compose 简介 Docker Compose 是一个用于定义和运行多容器 Dock…...
数据流中的第 K 大元素(703)
703. 数据流中的第 K 大元素 - 力扣(LeetCode) 解答: class KthLargest { public: //使用nums作为_q的底层存储,节省内存 KthLargest(int k, vector<int>& nums) : _k(k),…...
