设计模式--适配器模式(Adapter Pattern)

一、什么是适配器模式(Adapter Pattern)

适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口。适配器模式主要用于解决不兼容接口之间的问题,使得原本由于接口不匹配而无法一起工作的类能够协同工作。

适配器模式涉及以下几个核心角色:

  1. 目标接口(Target Interface):客户端所期望的接口,适配器将现有的接口转换成这个目标接口。
  2. 适配器(Adapter):适配器类实现了目标接口,同时持有一个需要被适配的对象。适配器通过适配被适配对象的接口,使其能够符合目标接口的要求。
  3. 被适配对象(Adaptee):需要被适配的现有类。它可能具有与目标接口不同的接口。

适配器模式的目标是使不兼容的接口能够一起工作,同时也可以在一些情况下用来重用现有的类,而无需修改其源代码。

适配器模式可以分为两种类型:

  1. 类适配器模式:使用继承的方式将适配器与被适配对象结合起来,使适配器可以调用被适配对象的方法并实现目标接口。
  2. 对象适配器模式:使用组合的方式将适配器与被适配对象结合起来,使适配器通过调用被适配对象的方法来实现目标接口。

适配器模式在现实世界中的例子是,将电子设备从一个插头类型适配到另一个插头类型,以使其能够连接到不同的电源插座。

适配器模式提供了一种方式来处理不同接口之间的集成问题,使得系统中不同部分可以协同工作,从而提高了代码的灵活性和可维护性。

二、类适配器模式的代码样例

以下是一个使用C++实现类适配器模式的简单示例:

#include <iostream>// 目标接口
class TargetInterface {
public:virtual void request() = 0;
};// 被适配的类
class Adaptee {
public:void specificRequest() {std::cout << "Adaptee's specificRequest called." << std::endl;}
};// 适配器类(类适配器)
class Adapter : public TargetInterface, public Adaptee {
public:void request() override {specificRequest();}
};int main() {TargetInterface* target = new Adapter();target->request();delete target;return 0;
}

在这个示例中,我们有一个目标接口 TargetInterface,它定义了客户端期望的接口。然后有一个被适配的类 Adaptee,它具有与目标接口不同的接口。最后,我们创建了一个适配器类 Adapter,它继承了目标接口 TargetInterface 并继承了被适配类 Adaptee。适配器类的 request 方法通过调用被适配类的 specificRequest 方法来实现目标接口。

在主函数中,我们通过创建适配器对象,并将其视为目标接口的实例,从而可以调用 request 方法来实现被适配类的功能。

这个示例展示了类适配器模式的基本概念,通过继承来适配被适配的类的接口,使其能够符合目标接口的要求。

三、对象适配器模式的代码样例

以下是一个使用C++实现对象适配器模式的简单示例:

#include <iostream>// 目标接口
class TargetInterface {
public:virtual void request() = 0;
};// 被适配的类
class Adaptee {
public:void specificRequest() {std::cout << "Adaptee's specificRequest called." << std::endl;}
};// 适配器类(对象适配器)
class Adapter : public TargetInterface {
public:Adapter(Adaptee* adaptee) : adaptee(adaptee) {}void request() override {adaptee->specificRequest();}private:Adaptee* adaptee;
};int main() {Adaptee* adaptee = new Adaptee();TargetInterface* target = new Adapter(adaptee);target->request();delete target;delete adaptee;return 0;
}

在这个示例中,我们依然有一个目标接口 TargetInterface,一个被适配的类 Adaptee,以及一个适配器类 Adapter。与之前不同的是,适配器类不再继承被适配的类,而是在构造函数中持有被适配类的实例。

适配器类的 request 方法通过调用被适配类的 specificRequest 方法来实现目标接口。

在主函数中,我们先创建了一个被适配类的实例 adaptee,然后将其传递给适配器类 Adapter 的构造函数来创建适配器对象。然后,我们通过适配器对象调用 request 方法来实现被适配类的功能。

这个示例展示了对象适配器模式的基本概念,通过组合和持有被适配的对象来适配其接口,从而使其能够符合目标接口的要求。

四、类适配器模式和对象适配器模式的区别

类适配器模式和对象适配器模式是适配器模式的两种不同实现方式,它们的区别主要体现在适配器与被适配对象之间的关系以及实现方式上。

类适配器模式:

  1. 关系:在类适配器模式中,适配器类通过继承被适配的类来实现适配。适配器同时拥有目标接口和被适配类的功能,因此可以通过调用被适配类的方法来实现目标接口。
  2. 实现方式:适配器类继承被适配类,可以直接访问被适配类的方法和属性,但也可能需要重新实现一些方法来适配目标接口。
  3. 结构复杂性:类适配器模式的结构相对较简单,但可能会受到被适配类的限制,因为继承只能应用于具有合适继承关系的类。

对象适配器模式:

  1. 关系:在对象适配器模式中,适配器类通过组合持有一个被适配的对象实例。适配器持有被适配对象的引用,通过调用被适配对象的方法来实现目标接口。
  2. 实现方式:适配器类在自己的方法中调用被适配对象的方法,实现了目标接口。适配器还可以在自己的方法中添加一些额外的逻辑。
  3. 灵活性:对象适配器模式更灵活,可以适配多个不同的被适配对象,而不受继承关系的限制。

选择哪种适配器模式:

  • 选择类适配器模式还是对象适配器模式取决于设计需求和被适配对象的特性。如果被适配对象是一个类,且希望通过继承来复用其功能,可以选择类适配器模式。如果被适配对象是一个接口或一个无法继承的类,或者希望适配多个不同的被适配对象,可以选择对象适配器模式。

总之,两种适配器模式都有各自的优势和用途,根据具体情况选择合适的实现方式。

五、使用适配器模式需要注意的问题

在使用适配器模式时,需要注意以下几个问题:

  1. 接口一致性:适配器模式的目的是将不兼容的接口转换成兼容的接口,但在适配过程中需要确保目标接口满足客户端的需求,否则可能会导致功能不正常或错误。
  2. 覆盖问题:在类适配器模式中,适配器类继承了被适配类的方法和属性。如果被适配类的方法与目标接口的方法同名,适配器可能需要覆盖被适配类的方法,以实现目标接口的需求。这可能导致子类方法的覆盖问题。
  3. 被适配对象的状态:在适配过程中,被适配对象的状态可能会受到影响。在适配器中调用被适配对象的方法时,需要确保对象的状态不会出现意外的变化。
  4. 灵活性和复用性:适配器模式可以在不同的场景中复用现有的类,但在适配过程中可能会引入一些特定的逻辑,这可能会影响到代码的灵活性和复用性。
  5. 过多的适配器:过度使用适配器模式可能会导致系统中存在大量的适配器类,从而增加代码的复杂性。需要根据实际情况权衡是否使用适配器模式。
  6. 性能问题:适配器模式可能会引入额外的开销,特别是在适配器的方法中涉及转换和逻辑时。需要在性能要求高的情况下进行评估和优化。

总之,适配器模式是一种用于解决接口不匹配问题的有用工具,但在使用时需要仔细考虑接口一致性、状态维护、代码复用等问题,以确保适配器能够正确地将不兼容的接口转换成兼容的接口。

在这里插入图片描述

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

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

相关文章

将数据类型,类名作为参数传递使用的方法

在开发中遇到一个问题&#xff0c;就是给了很多的数据类型&#xff0c;需要找出当前数据属于哪个数据类型。 举个例子&#xff0c;我们现在有一组数据类型<int, double, float, char, bool>&#xff0c;并给定一个数据char c&#xff1b;需要通过一个函数找出变量c是类型…

七层、四层和五层网络模型区别和联系

七层、四层和五层网络模型区别和联系 概述OSI网络7层模型&#xff08;概念型框架&#xff09;概述图片分析 四层模型概述常用协议OSI与TCP/IP四层的区别 五层模型概述三种网络模型对比 总结 概述 网络模型-七层模型&#xff08;OSI模型&#xff09;、五层协议体系结构和TCP/IP…

【提升接口响应能力的最佳实践】常规操作篇

文章目录 1. 并行处理简要说明CompletableFuture是银弹吗&#xff1f;测试案例测试结论半异步&#xff0c;半同步总结 2. 最小化事务范围简要说明编程式事务模板 3. 缓存简要说明 4. 合理使用线程池简要说明使用场景线程池的创建参数的配置建议 线程池的监控线程池的资源隔离 5…

SpringBoot权限认证

SpringBoot的安全 常用框架&#xff1a;Shrio,SpringSecurity 两个功能&#xff1a; Authentication 认证Authorization 授权 权限&#xff1a; 功能权限访问权限菜单权限 原来用拦截器、过滤器来做&#xff0c;代码较多。现在用框架。 SpringSecurity 只要引入就可以使…

ctfshow-web13 文件上传

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 首先看到是一个上传页面&#xff0c;测试其他无果&#xff0c;遂进行目录遍历&#xff0c;发现upload.php.bak文件 可以看到这里的限制条件&#xff0c;大小&#xff0c;以及内容&#xff0c;这里可以使用.use…

LeetCode669. 修剪二叉搜索树

669. 修剪二叉搜索树 文章目录 [669. 修剪二叉搜索树](https://leetcode.cn/problems/trim-a-binary-search-tree/)一、题目二、题解方法一&#xff1a;递归法方法二&#xff1a;迭代法 一、题目 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 hig…

使用秘籍|如何实现图数据库 NebulaGraph 的高效建模、快速导入、性能优化

本文整理自 NebulaGraph PD 方扬在「NebulaGraph x KubeBlocks」meetup 上的演讲&#xff0c;主要包括以下内容&#xff1a; NebulaGraph 3.x 发展历程NebulaGraph 最佳实践 建模篇导入篇查询篇 NebulaGraph 3.x 的发展历程 NebulaGraph 自 2019 年 5 月开源发布第一个 alp…

opencv进阶19-基于opencv 决策树cv::ml::DTrees 实现demo示例

opencv 中创建决策树 cv::ml::DTrees类表示单个决策树或决策树集合&#xff0c;它是RTrees和 Boost的基类。 CART是二叉树&#xff0c;可用于分类或回归。对于分类&#xff0c;每个叶子节点都 标有类标签&#xff0c;多个叶子节点可能具有相同的标签。对于回归&#xff0c;每…

【Acwing291】蒙德里安的梦想(状态压缩dp)详细讲解

题目描述 题目分析 显而易见的重要事实 首先&#xff0c;需要明白一个很重要的事实&#xff1a; 所有的摆放方案数所有横着摆放且合理的方案数 这是因为&#xff0c;横着的确定之后&#xff0c;竖着的一定会被唯一确定&#xff0c;举一个例子&#xff1a; ------唯一确定-…

RabbitMQ---订阅模型-Fanout

1、 订阅模型-Fanout Fanout&#xff0c;也称为广播。 流程图&#xff1a; 在广播模式下&#xff0c;消息发送流程是这样的&#xff1a; 1&#xff09; 可以有多个消费者 2&#xff09; 每个消费者有自己的queue&#xff08;队列&#xff09; 3&#xff09; 每个队列都要绑定…

Windows 10【压缩卷】操作报错【无法将卷压缩到超出任何不可移动的文件所在的点】的解决方法

目录 一、背景 二、原因 三、解决方法 3.1 Windows自带的碎片清理工具 3.1.1 操作步骤 3.1.2 操作结果 3.2 MyDefrag工具清理磁盘碎片 3.2.1 操作步骤 3.2.2 操作结果 3.3 Windows自带的事件查看器 3.3.1 操作步骤 3.3.2 操作结果 3.4 关闭虚拟内存并删除虚拟内存…

离谱事件解决方法2 无法定位程序输入点XXX于动态链接库XXX.dll

事情经过&#xff1a; 本人一只acmer&#xff0c;使用sublime编写代码&#xff0c;但是前两天在打开cpp类型的文件的时候显示报错如下&#xff1a; 这里的dll文件就是动态链接库&#xff0c;它并不是一个可执行文件&#xff0c;里面存放的是程序的函数实现过程&#xff08;公用…

django+MySQL计算机毕设之图片推荐系统(报告+源码)

图片推荐系统是在的数据存储主要通过MySQL。用户在使用应用时产生的数据通过Python语言传递给数据库。通过此方式促进图片推荐信息流动和数据传输效率&#xff0c;提供一个内容丰富、功能多样、易于操作的平台。述了数据库的设计&#xff0c;系统的详细设计部分主要论述了几个主…

Ubuntu释放VMware虚拟磁盘未使用空间

By: Ailson Jack Date: 2023.08.26 个人博客&#xff1a;http://www.only2fire.com/ 本文在我博客的地址是&#xff1a;http://www.only2fire.com/archives/152.html&#xff0c;排版更好&#xff0c;便于学习&#xff0c;也可以去我博客逛逛&#xff0c;兴许有你想要的内容呢。…

面试之快速学习计算机网络-http

1. HTTP常见状态码 2. 3开头重定向&#xff0c;4开头客户端错误&#xff0c;5开头服务端错误 2. HTTP 报文 1. start-line&#xff1a;请求行&#xff0c;可以为以下两者之一&#xff1a; 请求行&#xff1a; GET /hello-world2.html HTTP/1.1状态行&#xff1a;HTTP/1.1 200…

YOLOv8教程系列:三、K折交叉验证——让你的每一份标注数据都物尽其用(yolov8目标检测+k折交叉验证法)

YOLOv8教程系列&#xff1a;三、K折交叉验证——让你的每一份标注数据都物尽其用&#xff08;yolov8目标检测k折交叉验证法&#xff09; 0.引言 k折交叉验证&#xff08;K-Fold Cross-Validation&#xff09;是一种在机器学习中常用的模型评估技术&#xff0c;用于估计模型的性…

JavaScript(笔记)

目录 Hello World JavaScript 的变量 JavaScript 动态类型 隐式类型转换 JavaScript 数组 JavaScript 函数 JavaScript 中变量的作用域 对象 DOM 选中页面元素 事件 获取 / 修改元素内容 获取 / 修改元素属性 获取 / 修改 表单元素属性 获取 / 修改样式属性 新…

Java版B/S架构 智慧工地源码,PC、移动、数据可视化智慧大屏端源码

智慧工地是什么&#xff1f;智慧工地主要围绕绿色施工、安全管控、劳务管理、智能管理、集成总控等方面&#xff0c;帮助工地解决运营、管理方面各个难点痛点。在互联网的加持下促进项目现场管理的创新与发展&#xff0c;实现工程管理人员与工程施工现场的整合&#xff0c;构建…

[机缘参悟-102] :IT人 - 管理的本质?管理人与从事技术的本质区别?人性、冰山模型、需求层次模型

感悟&#xff1a; 管理的本质是&#xff1a;学习各种管理理论、方法、技能&#xff0c;克服自身的人性缺点、预防他人人性的恶点、利用他人的人性特点拿到结果&#xff0c;从而完成组织、管理者的上司、管理者自身、管理者下属的目标。管理中的问题&#xff0c;80%以上都人性问…

rtmp直播

技术要求&#xff1a;nginxnginx-rtmpffmpegVLC 跟着大佬走的&#xff1a; 传送门 准备工作&#xff1a; 首先需要一台公网ip的服务器 这是使用天翼云的弹性云主机&#xff1a;免费试用1个月 天翼云官网 点击关机&#xff0c;更多里面选择重置密码&#xff0c; 默认用户名为…