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

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

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

  • 适配器模式 Adapter Pattern
    • 1.1 基本介绍
    • 1.2 工作原理
  • 类适配器模式
  • 对象适配器模式
  • 接口适配器模式
  • 小结

适配器模式 Adapter Pattern

1.1 基本介绍

(1)适配器模式将某个类的接口转换成为客户端期望的另一个接口表示,主要的目的是兼容性,让原本应接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper).

(2)适配器模式属于结构型模式

(3)主要分为三类:类适配器模式、对象适配器模式、接口适配器模式

1.2 工作原理

  1. 适配器模式:将一个类的接口转换成为另一种接口,让原本接口不兼容的类可以兼容。
  2. 从用户的角度看不到被适配者,是解耦的。
  3. 用户调用适配器转换出来的目标接口方法,适配器再调用被适配者的相关接口方法。
  4. 用户收到反馈结果,感觉只是和目标接口交互。

类适配器模式

例子:电脑的电源适配器将(家庭用电)电压220伏特转换为5伏特,然后给电脑供电。

被适配者类:

package com.robin.adapter.classAdapter;// 被适配者类
public class Voltage220V {public int outPut220V(){int srcV = 220;System.out.println("[初始-家庭家用电压]电源电压:"+srcV+"伏特");return srcV;}
}

适配接口:

package com.robin.adapter.classAdapter;// 适配接口
public interface ICpVoltage5V {public int outPut();
}

电脑类:

package com.robin.adapter.classAdapter;public class Computer {public void charge(ICpVoltage5V iCpVoltage5V){int i = iCpVoltage5V.outPut();if (i==5){System.out.println("[电源适配器]电压为5伏特,可以开始充电使用了!");}else{System.out.println("[电源适配器]电压不正常,请检查或者更换电源适配器");}}
}

适配器类:

package com.robin.adapter.classAdapter;// 适配器类
public class CpVoltageAdapter extends Voltage220V implements ICpVoltage5V{@Overridepublic int outPut() {// 因为是继承关系,所以调用其父类的 电源电压输出int src = outPut220V();// 对220V电压进行简单转换int dest = src/44;return dest;}
}

测试客户端类:

package com.robin.adapter.classAdapter;public class Client {public static void main(String[] args) {Computer computer = new Computer();// 通过传入其适配器类的对象来进行充电computer.charge(new CpVoltageAdapter());// [电源适配器]电压为5伏特,可以开始充电使用了!}
}

类适配器模式的优点和缺点:

  1. 缺点:Java是单继承,但再类适配器模式中,适配器类需要继承被适配的类,失去了灵活性。并且被适配者类的方法都会在适配器类中暴露出来,增加了使用的成本。
  2. 优点:因为适配器类继承了被适配者类,所以适配器类可以根据需求,灵活的重写被适配者类。

对象适配器模式

对象适配器模式针对上面的类适配器模式进行了一些修改,通过合成复用来代替原本的继承关系

tip:对象适配器模式是适配器模式中常用的一种。

例子:还是上面的电脑电源的适配器问题,进行修改,将其改为对象适配器模式的。

我们只需要将适配器类中取消继承被适配的类,然后在适配器类中提供一个被适配类的成员变量及构造器即可。

在这里插入图片描述

被适配者类:

package com.robin.adapter.objectAdapter;// 被适配者类
public class Voltage220V {public int outPut220V(){int srcV = 220;System.out.println("[初始-家庭家用电压]电源电压:"+srcV+"伏特");return srcV;}
}

适配接口:

package com.robin.adapter.objectAdapter;// 适配接口
public interface ICpVoltage5V {public int outPut();
}

电脑类:

package com.robin.adapter.objectAdapter;public class Computer {public void charge(ICpVoltage5V iCpVoltage5V){int i = iCpVoltage5V.outPut();if (i==5){System.out.println("[电源适配器]电压为5伏特,可以开始充电使用了!");}else{System.out.println("[电源适配器]电压不正常,请检查更换电源适配器");}}
}

适配器类:

package com.robin.adapter.objectAdapter;// 适配器类
public class CpVoltageAdapter implements ICpVoltage5V {// 合成复用 将被适配类聚合到适配器类中private Voltage220V  voltage220V = null;// 提供被适配类的构造器public CpVoltageAdapter(Voltage220V voltage220V) {this.voltage220V = voltage220V;}// 重写适配接口中的方法@Overridepublic int outPut() {if (null != voltage220V){int srcV = voltage220V.outPut220V();int dstV = srcV/44;System.out.println("电源电压适配完成,电源电压="+dstV);return dstV;}return -1;}
}

客户端测试类:

package com.robin.adapter.objectAdapter;public class Client {public static void main(String[] args) {System.out.println("对象适配器模式");Computer computer = new Computer();computer.charge(new CpVoltageAdapter(new Voltage220V()));}
}

对象适配器模式与类适配器模式基本一致,只是通过合成复用代替继承,解决了类适配器产生的继承局限问题,使用成本更低更灵活。

接口适配器模式

接口适配器模式的思想:当不需要全部实现接口提供的方法时,可以先设计一个抽象类实现接口,并为该接口中的每个方法提供一个默认实现(空方法体),那么该抽象类的子类可以有选择的覆盖父类的某些方法来实现需求。

接口适配器模式适用于不想使用一个适配接口中所有方法的情况,按照自己的需求来挑选合适的方法自行实现。

比如,你要去旅游了,每个国家插座插孔和电压都不一样,你带了一个万能转换器(比如:wp-933)

在这里插入图片描述

然后各国插座如下:

在这里插入图片描述

暂且假定该万能转换插孔只提供一个空的插孔,需要你去自定义实现(我例子举得不是很好…有点牵强)

万能插孔适配接口:

package com.robin.adapter.interfaceadpter;// 万能插孔适配接口
public interface AllJacks {// 德国标准public void germanJack();// 欧洲标准public void europeanJack();// 中国,澳大利亚标准public void chinaAndOzJack();// 美国标准public void usaJack();//......
}

万能插孔抽象类实现接口中的所有方法,提供空方法体:

package com.robin.adapter.interfaceadpter;// 抽象类实现万能适配接口,实现全部接口方法,提供空方法体
public abstract class AbsAllJacksAdapter implements AllJacks {// 德国@Overridepublic void germanJack() {}// 欧洲@Overridepublic void europeanJack() {}// 中国和澳大利亚@Overridepublic void chinaAndOzJack() {}// 美国@Overridepublic void usaJack() {}
}

客户端测试:

package com.robin.adapter.interfaceadpter;public class Client {public static void main(String[] args) {// 中国电脑插孔为三孔,方形String srcJack = "[三孔]三方形孔";// 假设我现在旅行去美国AbsAllJacksAdapter absAllJacksAdapter = new AbsAllJacksAdapter(){@Overridepublic void usaJack() {System.out.println("=============使用万能转化器转换=============");// 美国电压为 100-130V,插孔为三孔,两方一圆String destJack = "[三孔]两方一圆孔";System.out.println("[插孔适配完毕]:"+srcJack+"==>"+destJack);}};absAllJacksAdapter.usaJack();}
}

在这里插入图片描述

小结

适配器模式的三种方式,也其实就是被适配类,如何被适配器类获取使用的(类=>继承,对象=>合成复用,接口)。Adapter适配器模式的最大作用就是将原本不兼容的接口融合在一起工作。


相关文章:

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

设计模式--适配器模式 Adapter Pattern适配器模式 Adapter Pattern1.1 基本介绍1.2 工作原理类适配器模式对象适配器模式接口适配器模式小结适配器模式 Adapter Pattern 1.1 基本介绍 (1)适配器模式将某个类的接口转换成为客户端期望的另一个接口表示&…...

PVE虚拟机篇-rest api

rest api官方介绍 Proxmox VE API rest api文档 rest api文档 rest api token 调用pve rest api ,有两种认证方式 Ticket Cookie Ticket Cookie的方式是最为推荐的,获取的方式为,通过post请求,发送用户名和密码到pve的server端获取tok…...

2022-2025学年面向中小学生的白名单全国性竞赛活动清单及官网地址链接

**资料来源:爬虫爬取。** 教育部办公厅 工业和信息化部办公厅关于公布 首批特色化示范性软件学院名单的通知 教育部办公厅 工业和信息化部办公厅关于公布首批特色化示范性软件学院名单的通知 - 中华人民共和国教育部政府门户网站 教育部办公厅关于2022-2025学年面向中小学生…...

Python 高级编程之生成器与协程进阶(五)

文章目录一、概述二、生成器1)生成器和迭代器的区别2)生成器创建方式1、通过生成器函数创建2、通过生成器表达式创建3)生成器表达式4)yield关键字5)生成器函数6)return 和 yield 异同7)yield的使…...

Django框架之视图和URL

视图和URL 站点管理页面做好了, 接下来就要做公共访问的页面了.对于Django的设计框架MVT. 用户在URL中请求的是视图.视图接收请求后进行处理.并将处理的结果返回给请求者.使用视图时需要进行两步操作 1.定义视图2.配置URLconf 1. 定义视图 视图就是一个Python函数&#xff0c…...

Python 的Tkinter包系列之七:好例子补充2

Python 的Tkinter包系列之七:好例子补充2 英汉字典(使用文本文件记录英语单词和解释)、简单的通信录(使用SQLite数据库记录人员信息) 一、tkinter编写英汉字典 先看效果图: 词典文件是一个文本文件&…...

每日一练-等差数列

等差数列🍀题目描述🌿解题思路🌸Python源码📧Summary📆Date: 2023年2月10日 🎬Author: 小 y 同 学 📃Classify: 蓝桥杯每日一练 🔖Language: Python 🍀题目描述 题意   …...

使用动态参数构建CUDA图

文章目录使用动态参数构建CUDA图使用显式 API 调用构建 CUDA 图使用流捕获构建 CUDA 图组合方法执行结果总结使用动态参数构建CUDA图 自从在 CUDA 10 以来,CUDA Graphs 已被用于各种应用程序。 上图将一组 CUDA 内核和其他 CUDA 操作组合在一起,并使用指…...

在Fortran中调用Python教程

前言Python是机器学习领域不断增长的通用语言。拥有一些非常棒的工具包,比如scikit-learn,tensorflow和pytorch。气候模式通常是使用Fortran实现的。那么我们应该将基于Python的机器学习迁移到Fortran模型中吗?数据科学领域可能会利用HTTP AP…...

04-PS人像磨皮方法

1.高斯模糊磨皮 这种方法的原理就是建立一个将原图高斯模糊后图层, 然后用蒙版加画笔或者历史画笔工具将需要磨皮的地方涂抹出来, 通过图层透明度, 画笔流量等参数来控制磨皮程度 1.新建图层(命名为了高斯模糊磨皮), 混合模式设置为正常, 然后选择高斯模糊, 模糊数值设置到看…...

nginx反向代理+负载均衡上传webshell重难点+apache漏洞

nginx反向代理 nginx 负载均衡 负载均衡的策略 1、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB… upstream mysvr { server 192.168.137.131; server 192.168.137.136; }2、weight:跟据配置…...

transition组件的使用

<template><button click"flag !flag">切换</button><transition name"fade"><div v-if"flag" class"box"></div></transition> </template><script setup lang"ts"&g…...

多行文本在块元素中垂直居中

单行文本垂直居中对齐 在块元素中&#xff0c;让单行文本居中&#xff0c;可以使用line-height等于块元素的高&#xff0c;即可让该单行文本垂直居中对齐。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><me…...

在 WebAssembly 中使用 C/C++ 和 libbpf 编写 eBPF 程序

作者&#xff1a;于桐&#xff0c;郑昱笙 eBPF&#xff08;extended Berkeley Packet Filter&#xff09;是一种高性能的内核虚拟机&#xff0c;可以运行在内核空间中&#xff0c;用来收集系统和网络信息。随着计算机技术的不断发展&#xff0c;eBPF 的功能日益强大&#xff0c…...

leveldb源码解析六——compact

compact分为manual_compaction、minor_compaction、major_compaction&#xff0c;统一由MaybeScheduleCompaction触发&#xff1a; void DBImpl::MaybeScheduleCompaction() {mutex_.AssertHeld();if (background_compaction_scheduled_) {// Already scheduled} else if (shu…...

数据结构(二):单向链表、双向链表

数据结构&#xff08;二&#xff09;一、什么是链表1.数组的缺点2.链表的优点3.链表的缺点4.链表和数组的区别二、封装单向链表1. append方法&#xff1a;向尾部插入节点2. toString方法&#xff1a;链表元素转字符串3. insert方法&#xff1a;在任意位置插入数据4.get获取某个…...

COCO物体检测评测方法简介

本文从ap计算到map计算&#xff0c;最后到coco[0.5:0.95:0.05] map的计算&#xff0c;一步一步拆解物体检测指标map的计算方式。 一、ap计算方法 一个数据集有多个类别&#xff0c;对于该数据库有5个gt&#xff0c;算法检测出来10个bbox&#xff0c;对于人这个类别来说检测有…...

记一次上环境获取资源失败的案例

代码结构以及资源位置 测试代码 RestController RequestMapping("/json") public class JsonController {GetMapping("/user/1")public String queryUserInfo() throws Exception {// 如果使用全路径, 必须使用/开头String path JsonController.class.ge…...

实战超详细MySQL8离线安装

在RedHat中&#xff0c;RPM Bundle 方式安装MySQL8。建议一定要用 RPM Bndle 版本安装&#xff0c;包全。官网下载&#xff1a;https://dev.mysql.com/downloads/mysql/1.卸载mariadb&#xff0c;会与MySQL安装冲突。rpm -qa | grep mariadb 查看有无mariadb如果有&#xff0…...

依赖倒置原则|SOLID as a rock

文章目录 意图动机:违反依赖倒置原则解决方案:C++中依赖倒置原则的例子依赖倒置原则的优点1、可复用性2、可维护性在C++中用好DIP的标准总结本文是关于 SOLID as Rock 设计原则系列的五部分中的 最后一部分。 SOLID 设计原则侧重于开发 易于维护、可重用和可扩展的软件。 在…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...