C++设计模式——Adapter(适配器)模式

一、Adapter模式是个啥?

适配器模式在软件开发的江湖里,可以说用途是非常广的。下面几个经典的场景来说明适配器模式的使用。

场景一

在这里插入图片描述

场景二

假如你正在开发一款股票市场监测程序, 它会从不同来源下载 XML 格式的股票数据, 然后向用户呈现出美观的图表。

在开发过程中, 你决定在程序中整合一个第三方智能分析函数库。 但是遇到了一个问题, 那就是分析函数库只兼容 JSON 格式的数据。
在这里插入图片描述

整合分析函数库之前的程序结构
你无法 “直接” 使用分析函数库, 因为它所需的输入数据格式与你的程序不兼容。
你可以修改程序库来支持 XML。 但是, 这可能需要修改部分依赖该程序库的现有代码。 甚至还有更糟糕的情况, 你可能根本没有程序库的源代码, 从而无法对其进行修改。
你可以创建一个适配器。 这是一个特殊的对象, 能够转换对象接口, 使其能与其他对象进行交互。

适配器模式通过封装对象将复杂的转换过程隐藏于幕后。 被封装的对象甚至察觉不到适配器的存在。 例如, 你可以使用一个将所有数据转换为英制单位 (如英尺和英里) 的适配器封装运行于米和千米单位制中的对象。

适配器不仅可以转换不同格式的数据, 其还有助于采用不同接口的对象之间的合作。 它的运作方式如下:
在这里插入图片描述

适配器实现与其中一个现有对象兼容的接口。
现有对象可以使用该接口安全地调用适配器方法。
适配器方法被调用后将以另一个对象兼容的格式和顺序将请求传递给该对象。
有时你甚至可以创建一个双向适配器来实现双向转换调用。

二、适配器模式代码示例

#include <iostream>
#include <string>
#include <sal.h>
using namespace std;// 需要适配的接口
class Target {
public:virtual void request() = 0;~Target(){std::cout << __FUNCTION__ << std::endl;}
};// 目标接口的实现
class ConcreteTarget : public Target {
public:void request() override {std::cout << "ConcreteTarget::request() called." << std::endl;}
};// 被适配的接口
class Adaptee {
public:virtual void adapteeRequest() = 0;
};// 被适配接口的实现
class ConcreteAdaptee : public Adaptee {
public:void adapteeRequest() override {std::cout << "ConcreteAdaptee::adapteeRequest() called." << std::endl;}
};// 适配器
class Adapter : public ConcreteTarget {
public:Adapter( _In_ Adaptee* adaptee) : m_adaptee(adaptee) {}void request() override {m_adaptee->adapteeRequest();}
private:shared_ptr<Adaptee> m_adaptee;
};int main() {/// 使用适配器shared_ptr<Target> client0(new Adapter(new ConcreteAdaptee));client0->request(); // 输出:ConcreteAdaptee::adapteeRequest() called/// 使用非适配器shared_ptr<Target> client1(new ConcreteTarget);client1->request(); // 输出:ConcreteTarget::request() called.return 0;
}

三、适用的场景

当你希望使用某个类, 但是其接口与其他代码不兼容时, 可以使用适配器类。

适配器模式允许你创建一个中间层类, 其可作为代码与遗留类、 第三方类或提供怪异接口的类之间的转换器。

如果您需要复用这样一些类, 他们处于同一个继承体系, 并且他们又有了额外的一些共同的方法, 但是这些共同的方法不是所有在这一继承体系中的子类所具有的共性。

你可以扩展每个子类, 将缺少的功能添加到新的子类中。 但是, 你必须在所有新子类中重复添加这些代码, 这样会使得代码有坏味道。

将缺失功能添加到一个适配器类中是一种优雅得多的解决方案。 然后你可以将缺少功能的对象封装在适配器中, 从而动态地获取所需功能。 如要这一点正常运作, 目标类必须要有通用接口, 适配器的成员变量应当遵循该通用接口。 这种方式同装饰模式非常相似。

四、参考

《适配器模式》 https://refactoringguru.cn/design-patterns/adapter

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

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

相关文章

Tomcat管理功能使用

前言 Tomcat管理功能用于对Tomcat自身以及部署在Tomcat上的应用进行管理的web应用。在默认情况下是处于禁用状态的。如果需要开启这个功能&#xff0c;需要配置管理用户&#xff0c;即配置tomcat-users.xml文件。 &#xff01;&#xff01;&#xff01;注意&#xff1a;测试功…

Photoshop Circular Text

Ctrl N 新增 现学现卖

QT作业1

自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面 头文件代码&#xff1a; #ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget> #include <QIcon> #include <QLabel> //标签类 #include <QMovie> //动图类 #include <…

redis-学习笔记(hash)

Redis 自身已经是 键值对 结构了 Redis 自身的键值对就是通过 哈希 的方式来组织的 把 key 这一层组织完成后, 到了 value 这一层, 还可以用 哈希类型 来组织 (简单的说就是哈希里面套哈希 [数组里面套数组 -> 二维数组] ) [ field value ] hset key field value [ field va…

深入了解Java Duration类,对时间的精细操作

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概6000多字&#xff0c;预计阅读时间长需要5分钟。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&#x…

【踩坑记录】from natten import NeighborhoodAttention1D

在配置forecast-mae环境的时候。 ./forecast-mae/src/model/layers/agent_embedding.py文件中 导入包的时候from natten import NeighborhoodAttention1D 报错&#xff0c; 解决办法&#xff0c;默认安装的是__version__ "0.14.2"版本的 出现这个问题可能是包损坏…

c++新经典模板与泛型编程:const修饰符的移除与增加

const修饰符的移除 让你来写移除const修饰符&#xff0c;你会怎么样来写&#xff1f; &#x1f602;&#x1f602;trait类模板&#xff0c;如下 #include <iostream>// 泛化版本 template<typename T> struct RemoveConst {using type T; };// 特化版本 template…

kafka入门(四):消费者

消费者 (Consumer ) 消费者 订阅 Kafka 中的主题 (Topic) &#xff0c;并 拉取消息。 消费者群组&#xff08; Consumer Group&#xff09; 每一个消费者都有一个对应的 消费者群组。 一个群组里的消费者订阅的是同一个主题&#xff0c;每个消费者接收主题的一部分分区的消息…

Stable Diffusion 系列教程 - 2 WebUI 参数详解

Stable Diffusion 的整个算法组合为&#xff1a; UNet VAE 文本编码器 UNet&#xff1a;就是我们大模型里的核心。 文本编码器&#xff1a;将我们的prompt进行encoder为算法能理解的内容&#xff08;可以理解为SD外包出去的项目CLIP&#xff09;。 VAE&#xff1a;对UNet生…

Java_LinkedList链表详解

目录 前言 ArrayList的缺陷 链表 链表的概念及结构 链表的种类 1.单向或双向 2.带头或不带头 3.循环或不循环 LinkedList的使用 什么是LinkedList LinkedList的使用 LinkedList的构造 LinkedList的其他常用方法介绍 LinkedList的遍历 ArrayList和LinkedList的…

el-tree数据量过大,造成浏览器卡死、崩溃

el-tree数据量过大&#xff0c;造成浏览器卡死、崩溃 场景&#xff1a;树形结构展示&#xff0c;数据超级多&#xff0c;超过万条&#xff0c;每次打开都会崩溃 我这里采用的是引入新的插件虚拟树&#xff0c;它是参照element-plus 中TreeV2改造vue2.x版本虚拟化树形控件&…

golang开发之个微机器人的二次开发

简要描述&#xff1a; 下载消息中的文件 请求URL&#xff1a; http://域名地址/getMsgFile 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型…

【Unity】Addressable包资源加载失败:CRC Mismatch.

Error while downloading Asset Bundle: CRC Mismatch. 是资源下载校验失败&#xff0c;但是资源和上次打包的资源是一样的。没有排查到原因&#xff0c;在谷歌搜索后看到 大概就是指Unity版本修改后打包&#xff0c;会破坏原来的CRC信息&#xff0c;导致导报出来的资源无法通…

Module build failed : Error : Vue packages version mismatch:

Vue packages version mismatch: - vue2.7.15 (E:\Workspace_ce\erp\erp-web\node_modules\vue\dist\vue.runtime.common.js) - vue-template-compiler2.6.11 (E:\Workspace_ce\erp\erp-web\node_modules\vue-template-compiler\package.json) 【问题解决了&#xff0c;我很不…

Mac电脑投屏AirServer 2024怎么下载安装激活许可期限

对于那些想要将 iPhone、iPad 或其他 iOS 设备上的小屏幕镜像到计算机上的大屏幕的人来说&#xff0c;AirPlay 是一个很好的工具。 基于此&#xff0c;AirServer 非常需要将您的 Mac 或 PC 变成 AirPlay 设备。 但是如何使用计算机上的设置对 iPhone 等 iOS 设备进行屏幕镜像&a…

【AIGC】Midjourney高级进阶版

Midjourney 真是越玩越上头&#xff0c;真是给它的想象力跪了~ 研究了官方API&#xff0c;出一个进阶版教程 命令 旨在介绍Midjourney在Discord频道中的文本框中支持的指令。 1&#xff09;shorten 简化Prompt 该指令可以将输入的Prompt为模型可以理解的语言。模型理解语言…

【C++ 程序设计入门基础】- 第3节-循环结构02

目录 while 语句 案例 while 循环 输入一个整数 n &#xff0c;输出 1~n 的所有整数。 查看运行结果&#xff1a; while 语句结构解析 do while 语句 案例 do while 循环 输入一个整数n&#xff0c;输出1&#xff5e;n的所有整数。 查看运行结果 while、do while的区别 …

我的NPI项目之Android 安全系列 -- Android Strongbox 初识

从Android9(Pie)开始,Google强烈建议支持Strongbox. 具体描述如下: 一直到目前的Android14. 对应的内容也一并贴出来: 说人话就是Android开始通过独立于主SoC的单元进行密钥存储了。 通常&#xff0c;这样的单元就是我们通常称作的Secure Element&#xff08;SE&#xff09;&am…

linux7安装python3.12.1教程

1.下载tar.gz包 地址&#xff1a;Python Release Python 3.12.1 | Python.org 2.上传包到linux服并解压 cd /home/local/ ll tar -zxvf Python-3.12.1.tgz 3.安装编译python所需环境 yum install -y gcc yum install -y zlib* yum -y install zlib-devel bzip2-devel opens…

MATLAB | 官方举办的动图绘制大赛 | 第四周(收官周)赛情回顾

MATHWORKS官方举办的迷你黑客大赛第三期(MATLAB Flipbook Mini Hack)圆满结束&#xff0c;虽然我的水平和很多大佬还有比较大的差距&#xff0c;但所有奖也算是拿满了&#xff1a; 专家评选前三名&#xff0c;以及投票榜前十&#xff1a;~ 每周的阶段性获奖者&#xff1a; 下面…