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

news2024/11/28 22:32:50

一、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.coloradmin.cn/o/1300140.html

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

相关文章

USB host是如何区分reset、disconnect以及suspend?

如题。 reset和disconnect 在OTG2.0中&#xff0c;当其配置程host模式&#xff0c;当host发送reset时D/D-线都为低电平&#xff0c;这是USB协议侧的复位&#xff08;与上电复位不同&#xff0c;协议上的复位是为了对连接的dev进行枚举&#xff0c;例如对端点0进行set address…

分类预测 | SSA-HKELM-Adaboost麻雀算法优化混合核极限学习机的数据分类预测

分类预测 | SSA-HKELM-Adaboost麻雀算法优化混合核极限学习机的数据分类预测 目录 分类预测 | SSA-HKELM-Adaboost麻雀算法优化混合核极限学习机的数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.SSA-HKELM-Adaboost麻雀算法优化混合核极限学习机的数据分类…

完整方案开放下载!详解中国移动《通信网络中量子计算应用研究报告》

8月30日&#xff0c;中国移动在第四届科技周暨战略性新兴产业共创发展大会上重磅发布了《通信网络中量子计算应用研究报告》。 玻色量子作为中国移动在光量子计算领域的唯一一家合作企业兼战投企业&#xff0c;在量子计算应用于通信行业达成了深入合作&#xff0c;并在5G天线多…

【代码随想录】算法训练计划41

dp 1、343. 整数拆分 题目&#xff1a; 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 输入: n 10 输出: 36 解释: 10 3 3 4, 3 3 4 36。 思路…

电工--基本放大电路

电压放大倍数、输入电阻和输出电阻是放大电路的三个主要性能指标 共发射极基本交流放大电路 晶体管&#xff1a;电流放大作用。能量较小的输入信号通过晶体管的控制作用&#xff0c;去控制电源所共给的能量&#xff0c;以在输出端获得一个能量较大的信号 集电极电源电压&#…

接口测试 —— Jmeter读取数据库数据作测试参数

1、添加Jdbc Request 2、添加ForEach控制器(右键线程组->逻辑控制器->ForEach控制器) ①输入变量的前缀&#xff1a;mobilephone&#xff1b; 从jdbc request设置的变量得知&#xff0c;我们要取的值为mobilephone_1、mobilephone_2、mobilephone_3......所以这里输入m…

基于单片机智能病床呼叫系统设计

**单片机设计介绍&#xff0c;基于单片机智能病床呼叫系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的智能病床呼叫系统是一种利用单片机技术设计的医疗设备&#xff0c;它能够帮助病人在住院期间快速、方便…

侯捷C++ (二--STL标准库)

CSTL标准库与泛型编程 STL六大部件 容器 Containers分配器 Allocators 一种用来修饰容器或仿函数或迭代器接口的东西算法 Algorithms迭代器 Iterators适配器 Adapters仿函数 Functors 容器 前闭后开 大致分为两种容器&#xff1a;序列容器&#xff0c;关联容器 所谓关联容器…

安装 DevEco Studio 后不能用本地 Node.js 打开

安装 DevEco Studio 后第一次打开时&#xff0c;不能用本地 Node.js 打开 答&#xff1a;因为本地 Node.js 文件夹名字中有空格 Node.js路径只能包含字母、数字、“。”、“_”、“-”、“:”和“V” 解决方法&#xff1a; 1.修改文件夹名称 2.重新下载 注意&#xff1a;找一…

Verilog基础:$random系统函数的使用

相关阅读 Verilog基础​编辑https://blog.csdn.net/weixin_45791458/category_12263729.html $random系统函数语法的BNF范式如下所示&#xff0c;有关BNF范式相关内容&#xff0c;可以浏览以往文章Verilog基础&#xff1a;巴科斯范式(BNF)。 $random系统函数在每次调用时返回一…

【Docker】进阶之路:(一)容器技术发展史

【Docker】进阶之路&#xff1a;&#xff08;一&#xff09;容器技术发展史 什么是容器为什么需要容器容器技术的发展历程Docker容器是如何工作的 什么是容器 容器作为一种先进的虚拟化技术&#xff0c;已然成为了云原生时代软件开发和运维的标准基础设施。在了解容器技术之前…

14-1、IO流

14-1、IO流 lO流打开和关闭lO流打开模式lO流对象的状态 非格式化IO二进制IO读取二进制数据获取读长度写入二进制数据 读写指针 和 随机访问设置读/写指针位置获取读/写指针位置 字符串流 lO流打开和关闭 通过构造函数打开I/O流 其中filename表示文件路径&#xff0c;mode表示打…

C++学习笔记:继承

继承 什么是继承?继承的写法基类和派生类的赋值转换继承中的作用域派生类的默认成员函数单继承,多继承,虚拟继承is-a 和 has-a 什么是继承? 继承是C语言面向对象的三大特性之一&#xff0c;是面向对象程序设计使代码可以复用的最重要的手段,基本都是在一个类的基础上为了增加…

十九、FreeRTOS之FreeRTOS软件定时器

本节主要需要掌握以下内容&#xff1a; 1&#xff0c;软件定时器的简介&#xff08;了解&#xff09; 2&#xff0c;软件定时器的状态&#xff08;熟悉&#xff09; 3&#xff0c;单次定时器和周期定时器&#xff08;熟悉&#xff09; 4&#xff0c;软件定时器结构体成员介…

Unity中Batching优化的GPU实例化(2)

文章目录 前言一、GPU实例化的Shader准备步骤1、在Pass中声明实例化需要的变体2、UNITY_VERTEX_INPUT_INSTANCE_ID 在顶点着色器的输入(appdata)和输出(v2f可选)中添加(uint instanceID : SV_InstanceID). 前言 在上篇文章中&#xff0c;我们做了一些GPU实例化的前置准备&…

查看NVIDIA CUDA版本号的四种方法

查看CUDA版本号这里有三种方法。 nvidia-smi 运行nvidia-smi命令&#xff1a; 右上角可以看到CUDA版本号。 CUDA Toolkit 下载地址&#xff1a;https://developer.nvidia.com/cuda-downloads $nvcc -V nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2023 NV…

【数据结构 — 排序 — 交换排序】

数据结构 — 排序 — 交换排序 一.交换排序1.基本思想2.冒泡排序2.1.算法讲解2.2.代码实现2.2.1.函数定义2.2.2.算法接口实现2.2.3.测试代码实现2.2.4.测试展示 3.快速排序3.1.算法讲解3.2.各大算法分别单独实现3.2.1快速排序hoare版本3.2.2.快速排序hoare改进版三数取中选key法…

四:爬虫-Cookie与Session实战

四&#xff1a;Cookie与Session实战 ​ 在浏览网站的过程中&#xff0c;我们经常会遇到需要登录的情况&#xff0c;有些页面只有登录之后才可以访问。在登录之后可以连续访问很多次网站&#xff0c;但是有时候过一段时间就需要重新登录。还有一些网站&#xff0c;在打开浏览器…

基于SSM框架的仓库管理系统

基于SSM框架的仓库管理系统 文章目录 基于SSM框架的仓库管理系统 一.引言二.系统设计三.技术架构四.功能实现五.界面展示六.源码获取 一.引言 现代商业环境中&#xff0c;仓库管理对于企业的运营效率和客户满意度至关重要。传统的手工管理方式已经无法满足日益复杂的仓储需求。…

51系列--基于MPX4250的压力计仿真设计

本文介绍基于MPX4250的压力计仿真设计&#xff08;完整仿真源文件及代码见文末链接&#xff09; MPX4250是一种线性度极强的一种压力传感器&#xff0c;它的线性范围为20-250kpa,测量范围也比较广泛&#xff0c;适用于大多数场合的压力检测。 仿真图如下 仿真运行视频 51系列…