适配器模式-C++实现

适配器是一种结构型设计模式,用于将一个接口转换为另一个客户端所需要的接口。该模式通过创建一个适配器对象,使不兼容的接口可以协同工作。

适配器模式主要分为三个角色:适配器类、目标类、适配者类。

适配器模式分为对象适配器类适配器

对象适配器是基于组合实现,而类适配器通过多继承方式实现。在类适配器模式中,适配器类即继承目标类,又继承适配者类,从而能够调用适配者类的方法,并将其适配到目标类身上。相比之下,对象适配器更加灵活,因为它是继承目标类、定义适配者对象,在目标类方法中调用适配者对象的方法,这种方法支持我们可以适配多个适配者类(也就是定义多个适配者类),所以更加灵活。

主要区别包括:

1、实现方式:对象适配器使用对象组合(composition)实现适配器功能,而类适配器使用多重继承(multiple inheritance)实现适配器功能。

2、关系:对象适配器通过持有适配者对象的引用来连接适配器与适配者,类适配器通过同时继承目标类和适配者类来连接适配器与适配者。

3、灵活性:对象适配器更加灵活,可以适配多个适配者类,并且可以动态切换适配者;类适配器在编译时就确定了适配者类,无法在运行时动态切换适配者。

因为类适配器是在编译时确定的,所以基本没有优点,我们这里举一个对象适配器的例子。

假设我们现在有一个模拟动物各种行为的机器人,它定义了叫喊和奔跑两种方法,我们现在希望不修改现有代码的基础上让机器人模仿狗的叫声和跑步姿势。

在这里插入图片描述

#include <iostream>
#include <memory>// 目标抽象类Robot
class IRobot
{
public:virtual ~IRobot() {}virtual void Cry() = 0;virtual void Run() = 0;
};// 适配者类 狗
class Dog
{
public:void Wang(){std::cout << "狗叫" << std::endl;}void Run(){std::cout << "狗跑" << std::endl;}
};// 适配器类
class DogAdapter: public IRobot
{
public:DogAdapter(std::shared_ptr<Dog> _dog): dog_(_dog){}virtual void Cry() override{std::cout << "机器人模仿: ";if (dog_)dog_->Wang();}virtual void Run() override{std::cout << "机器人模仿: ";if (dog_)dog_->Run();}private:std::shared_ptr<Dog> dog_;
};

测试:

void TestAdapter()
{std::shared_ptr<IRobot> robot = std::make_shared<DogAdapter>(std::make_shared<Dog>());robot->Cry();robot->Run();
}

输出:

机器人模仿: 狗叫
机器人模仿: 狗跑

为了实现这个示例,我们创建了一个抽象目标类 IRobot,定义了叫和跑两种方法。创建了一个具体适配者类 Dog,同样实现了叫和跑两种方法,创建了一个适配器类 DogAdapter继承IRobot,并且定义一个适配者对象,重写这两种方法,在这两种方法里调用适配者对象的叫和跑两种方法到达机器人模拟狗叫和狗跑的目的。

适配器模式遵循以下设计原则:

1、单一职责原则:适配器类的主要责任是将不兼容的接口转换为兼容的接口,它应该只关注适配工作,不涉及其他功能。

2、开闭原则:适配器模式允许系统在不修改现有代码的情况下引入新的适配器类,以适应不同的适配需要。

优点:

1、增加代码的可重用性:适配器模式可以重用现有的适配者类,无需修改其代码,增加系统的可维护性和灵活性。

2、系统的解耦:适配器模式将客户端和适配者类进行解耦,使得客户端不需要关心具体适配者类的实现细节。而且适配者类发生改变不影响客户端。

3、提高系统的扩展性:适配者模式允许在不修改现有代码的情况下增加新的适配器类以适应不同的接口需求。

缺点:

1、增加系统的复杂性:因为引入了适配器类,增加了系统的复杂性,对于简单系统可能显得过于繁琐。

2、增加运行时的开销:由于适配器需要进行接口转换和数据转换,可能会引入一些系统运行时的开销。

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

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

相关文章

信号收尾.

sigaction 信号捕捉 它也是信号捕捉&#xff0c;不仅能处理普通信号还能处理实时信号&#xff0c;但我们不管实时信号 我们发现函数名和形参中结构体名一样都是sigaction&#xff0c;这在c/c中允许吗&#xff1f; 不建议&#xff0c;但是可以 signo你要捕捉几号信号 输入型参…

HarmonyOS应用开发者基础认证考试题目及答案

一、判断题 Ability是系统调度应用的最小单元&#xff0c;是能够完成一个独立功能的组件。一个应用可以包含一个或多个Ability。 正确(True) 所有使用Component修饰的自定义组件都支持onPageShow&#xff0c;onBackPress和onPageHide生命周期函数。 错误(False) 每调用一次ro…

老泮识趣:难忘何家桥

回忆何家桥往事&#xff0c;写了篇《消失的何家桥》&#xff0c;没想到点击率如此高&#xff0c;出乎意料。网友的共鸣可见&#xff0c;城市发展的今天&#xff0c;乡情是个美好的存在&#xff0c;清贫、朴实&#xff0c;丝毫不影响美感。由于大家的鼓励&#xff0c;触动了我再…

基于Netty实现TCP通信

创建一个Maven项目添加下面依赖 <dependencies><!-- 日志依赖 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.32</version></dependency><dependency><g…

TCP 连接断开

1&#xff1a;TCP 四次挥手过程是怎样的&#xff1f; 客户端打算关闭连接&#xff0c;此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文&#xff0c;也即 FIN 报文&#xff0c;之后客户端进入 FIN_WAIT_1 状态。 服务端收到该报文后&#xff0c;就向客户端发送 ACK 应答报文…

【微信小程序】保存多张图片到本地相册 wx.saveImageToPhotosAlbum

这里写目录标题 微信小程序检测是否有存储权限wx.getSetting 图片上传从HTML中提取img标签的src属性多图片下载 微信小程序检测是否有存储权限 wx.getSetting 上传前判断是否开启存储权限&#xff0c;如果不检测直接上传会出现fail的情况 var _this this wx.getSetting({su…

阿里云崩溃了,为什么你没有收到补偿?【补偿领取方式放文末】

事情经过 北京时间11月27日&#xff0c;阿里云部分地域云数据库控制台访问出现异常。据悉&#xff0c;从当日09:16起&#xff0c;阿里云监控发现北京、上海、杭州、深圳、青岛、香港以及美东、美西地域的数据库产品(RDS、PolarDB、Redis等)的控制台和OpenAPI访问出现异常&…

PHP在线日语学习平台

有需要请加文章底部Q哦 可远程调试 PHP在线日语学习平台 一 介绍 此日语学习平台基于原生PHP开发&#xff0c;数据库mysql。系统角色分为用户和管理员。(附带参考设计文档) 技术栈&#xff1a;phpmysqlphpstudyvscode 二 功能 学生 1 注册/登录/注销 2 个人中心 3 查看课程…

C#开发的OpenRA游戏之属性SelectionDecorations(14)

C#开发的OpenRA游戏之属性SelectionDecorations(14) 前面分析选择类时,还有一个功能,就是把选中物品的状态和生命值显示出来。 它是通过下面的函数来实现: protected override IEnumerable<IRenderable> RenderSelectionBars(Actor self, WorldRenderer wr, bool …

this.$nextTick与this.$set,解决拖拽表格没有刷新问题!

一&#xff1a;this.$nextTick的用法 将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它&#xff0c;然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样&#xff0c;不同的是回调的 this 自动绑定到调用它的实例上。 原因是&#xff0c;Vue是异步执行DOM更…

kubernetes(k8s)容器内无法连接同所绑定的Service ClusterIP问题记录

kubernetes(k8s)容器内无法连接同所绑定的Service ClusterIP问题记录 1. k8s环境 k8s使用kubernetes-server-linux-amd64_1.19.10.tar.gz 二进制bin 的方式手动部署 k8s 版本: [rootmaster ~]# kubectl version Client Version: version.Info{Major:"1", Minor:&…

CentOS7安装RabbitMQ

服务器系统版本&#xff1a;CentOS7 安装RabbitMq版本&#xff1a;3.7.18 将此安装包目录下的两个文件上传到服务/usr/local/rabbitmq中备用。 安装Erlang依赖包 rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm安装RabbitMQ安装包(需要联网) yum install -y rabbitmq-server-3.7.1…

yml转properties工具

目前搜索到的大部分代码都存在以下问题&#xff1a; 复杂结构解析丢失解析后顺序错乱 所以自己写了一个&#xff0c;经过不充分测试&#xff0c;基本满足使用。可以直接在线使用 在线地址 除了yml和properties互转之外&#xff0c;还可以生成代码、sql转json等&#xff0c;可…

深入解析进程

在现代计算机系统中&#xff0c;进程是一个核心概念&#xff0c;它代表了程序的执行实例。通过并发执行多个进程&#xff0c;计算机能够提高效率和资源利用率。 1. 进程的概念 进程是指在计算机系统中正在执行的程序的实例。每个进程都有自己的地址空间、寄存器集合、堆栈和文…

【Linux】OpenSSH 命令注入漏洞(CVE-2020-15778)(iptables屏蔽22端口方式)

背景 漏洞名称&#xff1a;OpenSSH 命令注入漏洞(CVE-2020-15778) 详细描述&#xff1a;OpenSSH&#xff08;OpenBSD Secure Shell&#xff09;是OpenBSD计划组的一套用于安全访问远程计算机的连接工具。该工具是SSH协议的开源实现&#xff0c;支持对所有的传输进行加密&#…

java:lombok库方便的使用@Getter和@Setter

背景 Lombok是一个Java库&#xff0c;它通过注解减少了大量常规代码&#xff0c;例如getter和setter方法&#xff0c;equals&#xff0c;hashCode&#xff0c;toString等方法。使用Lombok可以减少模板代码的编写&#xff0c;使代码更简洁&#xff0c;更易于阅读和维护。 常用…

DaVinci Resolve Studio达芬奇软件 18.6.3

DaVinci Resolve Studio 18是一款专业的视频编辑和调色软件&#xff0c;适用于电影、电视节目、广告等各种视觉媒体的制作。它具有完整的后期制作功能&#xff0c;包括剪辑、调色、特效、音频处理等。 以下是DaVinci Resolve Studio 18的主要特点&#xff1a; - 提供了全面的视…

Go map类型

一、map介绍 1、map说明 map是一种无须的基于key-value的数据结构&#xff0c;Go语言中的map是引用类型&#xff0c;必须初始化才能使用Go语言中map的定义语法如下&#xff1a;map[KeyType]ValueType其中 KeyType&#xff1a;表示键的类型ValueType&#xff1a;表示键对应的值…

CAN网络出现错误帧从哪些方面去分析解决

标题&#xff1a;CAN网络出现错误帧从哪些方面去分析 实例1&#xff1a; 断电重启后&#xff0c;会有错误帧产生。 检查方案&#xff1a; 查看收发模块的初始化、使能是否在发送CAN报文之前完成&#xff1f; 实例2&#xff1a; 周期性报文&#xff0c;有时会冒出一帧错误帧&…

[Java][单列集合具体操作]以ArrayList为例讲解“增”“删”“查”“改”操作

我们来研究List系列的集合 List相较于set 优势在于&#xff1a; 1.有序的 2.有索引的 3.可重复的 这里最关键的是2.有索引的&#xff1a;因为这点我们可以做更多拓展性的操作 List是Collection中的一种 Collection中的方法List都继承了 索引拓展出的方法 是add(索引位置&#x…