当前位置: 首页 > news >正文

适 配 器 模 式

前阵子,笔者在网上淘来一个二手显示屏来搭配我装好的主机,但是送到手上后我却找不到电源适配器的踪迹。于是我就在家找了根电源线接上了显示屏,倒是能亮,就是屏幕闪得和机关枪似的。这是因为我的显示屏需要12V的供电,我找的这根是5V的……

电源适配器的作用就是把220V的交流电转换成显示器的电压,起到一个转换的作用,我们的适配器模式(Adapter)也是这个意思。


介绍

适配器模式是一种结构型模式,旨在解决不同接口间的不兼容问题。

在一些情况下,我们可能需要一些老的代码接口放在新的环境,这时就可以考虑使用适配器模式了。

适配器模式有以下三个角色:

1、目标接口,即适配器类的统一接口,规范了每一个适配器的行为。也能够允许用户灵活切换适配器。

2、适配者类,其实更像是“被适配者“,就是被适配器转换的主人公,相当于电源适配器转换的220V电源。

3、适配器类,实际发生转换的地方,是目标接口的具体实现,即电源适配器本身。

根据适配者与适配器的关系,适配器又可以被分为类适配器(继承)和对象适配器(组合或委托)。而且,适配器模式一般在开发的初阶段很难用得到,而是会用在已有的代码中解决存在的问题。

类适配器

这里假设我们要调用一个人物移动的方法,他规定了我们上下左右的移动方法。但是我们只需要左右移动就好了,这时就可以使用适配器模式,达到简化参数的作用了,这也是适配器模式使用的一个关键场景。

#include<iostream>
using namespace std;
/*目标接口*/
class Target {
public:
virtual void request(int left, int right) = 0; //目标接口方法
virtual ~Target() = default;
};
/*适配者*/
class Adaptee {
public:
void move(int W, int A, int S, int D) {cout << "按下W后,在y轴给予一个大小为" << W << "的速度" << endl;cout << "按下A后,在x轴给予一个大小为" << -A << "的速度" << endl;cout << "按下S后,在y轴给予一个大小为" << -S << "的速度" << endl;cout << "按下D后,在x轴给予一个大小为" << D << "的速度" << endl;}
};
/*适配器*/
//类适配器模式,使用继承的方式链接适配器与适配者
class Adapter : public Target, public Adaptee {
public:
//只需要用到左与右的速度,所以将上与下的速度设置为0
void request(int left, int right) override {
//调用适配者的方法
move(0, left, 0, right);}
};

可以看到,这里的适配器和适配者是通过继承的关系连接的。但是继承的方法没有灵活性,有着只能单一继承的关系,所以更推荐下面组合的方式连接。

对象适配器

这里再假设我们需要做一个音频适配器,原本的音频是MP3格式的,而我们新环境需要一个OGG格式的音频,这时的适配器起到了转换数据的作用,也是适配器的一个关键场景。

#include<iostream>
using namespace std;
/*目标接口*/
class Target {
public:
virtual void request() = 0; //目标接口方法
virtual ~Target() = default;
};
/*适配者*/
class Adaptee {
public:
void playMusic() {cout << "我播放了一段mp3音频" << endl;}
};
/*适配器*/
//类适配器模式,使用继承的方式链接适配器与适配者
class Adapter : public Target {
public:Adaptee* adaptee;
//只需要用到左与右的速度,所以将上与下的速度设置为0
void request() override {
//调用适配者的方法adaptee->playMusic();}
private:
void convert() {cout << "您输出的音频已经成功转换!" << endl;cout << "我播放了一段ogg音频" << endl;}
};

这样一来,适配器与适配者通过组合的方式连接,更灵活。实际开发中也是类似的框架。


小结

这就是适配器模式的使用方法了,常常用来连结新旧代码或是实现数据转换,总体来说非常简单,不难理解。

如有补充交流欢迎留言,我们下次再见~

参考列表:

菜鸟教程-设计模式:www.runoob.com 

http://www.lryc.cn/news/608478.html

相关文章:

  • 电力系统分析笔记:发电机与变压器的数学建模与运行状态详解
  • SPI通信中CS片选的两种实现方案:硬件片选与软件片选
  • Anthropic:跨越生产效能拐点的AI增长飞轮
  • Munge 安全认证和授权服务的工作原理,以及与 Slurm 的配合
  • 交互 Codeforces Round 1040 Interactive RBS
  • 深入 Go 底层原理(十一):Go 的反射(Reflection)机制
  • 基于深度学习的医学图像分析:使用GAN实现医学图像增强
  • SpringBoot 启动富文本文字更改
  • 基于 LightGBM 的二手车价格预测
  • 一种基于入侵杂草优化算法(IWO)的聚类算法,并与K-Means、高斯混合模型(GMM)进行对比,Matlab
  • 用键盘快速移动Word和WPS文字中的选中段落
  • 【笔试真题】2024秋招京东后端开发岗位-第一批笔试
  • 数据链路层、NAT、代理服务、内网穿透
  • 使用 MySQL Shell 进行 MySQL 单机到 InnoDB Cluster 的数据迁移实践
  • 数字化生产管理系统设计
  • 从零开始构建AI Agent评估体系:12种LangSmith评估方法详解
  • cuda编程笔记(12)--学习cuFFT的简单使用
  • Java单元测试和设计模式
  • 【LeetCode 热题 100】739. 每日温度——(解法一)单调栈+从右到左
  • 【语音技术】什么是动态实体
  • 【Django】-6- 登录用户身份鉴权
  • Mybatis学习之获取参数值(四)
  • 第14届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2023年1月15日真题
  • STM32学习记录--Day6
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘seaborn’问题
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现道路车辆事故的检测识别(C#代码UI界面版)
  • SpringBoot 服务器配置
  • 面经——电子电路技术知识详解
  • 【Python3教程】Python3高级篇之网络编程
  • 文心4.5开源测评:国产大模型的轻量化革命与全栈突破