学习设计模式之适配器模式,但是宝可梦

前言

作者在准备秋招中,学习设计模式,做点小笔记,用宝可梦为场景举例,有错误欢迎指出。

适配器模式

意图:将一个类的接口转换成客户希望的另一个接口

主要解决:把现有对象放到新环境里,而新环境要求的接口,现有对象不满足

何时使用:现有的类被需要,而这个类的接口不符合要求;建立一个可复用的类,用于让彼此之间无关的类或未来可能引入的类可以一起工作

适配器模式有3个角色:

  • 目标接口 (Target):当前系统业务期待的接口
  • 适配者类:被适配的现有组件的接口
  • 适配器类:一个转换器,继承或引用适配者对象,把适配者接口转为目标接口

1 情景假设

现在我们假设这样一个场景:小智在绿宝石的存档中,有一只巨tm强的裂空座,性格好,个体高,努力值也刷得完美。现在已经发售了朱紫,他还想用这只裂空座,但是问题来了,绿宝石是GBA主机的游戏,朱紫是Switch主机的游戏,他们存储数据的格式不同啊!这怎么办呢?那么就只能推出一个适配器,把GBA的数据转化成Switch的数据,把裂空座从绿宝石移植到朱紫,可能熟悉宝可梦游戏的朋友已经想到了,Pokemon Home就是干这个事的,所以我们可以把这个故事中的角色抽象为适配器模式需要的三个角色:

  • 目标接口:Switch数据
  • 适配者类:GBA数据
  • 适配器类:Pokemon Home

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XgCLolGk-1692546675681)(D:\笔记笔记笔记\设计模式.assets\image-20230820232858251.png)]

2 代码示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ZaJigJx-1692546675681)(D:\笔记笔记笔记\设计模式.assets\image-20230820232203323.png)]

现有的接口,就是老版本GBA游戏:

public interface GbaGame {void usePokemon(String dataFormat);
}public class EmeraldVersion implements GbaGame{/*** 在绿宝石中使用宝可梦*/public void usePokemon(String dataFormat, String version) {System.out.println("Go! Rayquaza! (In " + version + " Version)");}public void usePokemon() {System.out.println("Go! Rayquaza! (In GBA Version )");}
}

有绿宝石一个实现类,然而,现在游戏已经到了朱紫版本,需要的是Switch上的数据:

public interface NsGame{void usePokemon(String dataFormat);
}public class ScarletVersion implements NsGame{public void usePokemon(String dataFormat){if ("nsData".equals(dataFormat)){// 内置功能,使用当前版本的宝可梦System.out.println("Go! Chikorita (Get In Scarlet Version)");}}
}

于是为了让NS端适配GBA的数据,我们需要一个适配器,这个适配器要有旧版本的属性(因为适配器是为已有的类设计的)

/*** Pokemon Home*/
public class DataAdapter implements GbaGame{GbaGame gbaGame; // 旧世代public DataAdapter(GbaGame gbaGame) {this.gbaGame = gbaGame;}@Overridepublic void usePokemon(String dataFormat) {if("gbaData".equals(dataFormat)){gbaGame.usePokemon(dataFormat);}}
}

所以,要在新版本(NsGame)中使用旧版本的数据,新版本应该是:

public class ScarletVersion implements NsGame{DataAdapter dataAdapter;public void usePokemon(String dataFormat){if ("gbaData".equals(dataFormat)){dataAdapter = new DataAdapter(new EmeraldVersion());dataAdapter.usePokemon(dataFormat, "Switch");}else if ("nsData".equals(dataFormat)){// 内置功能,使用当前版本的宝可梦System.out.println("Go! Chikorita (Get In Scarlet Version)");}}
}

注意:这里并不违背“开闭原则”,因为前面的ScarletVersion类只是为了说明逻辑,并不是对代码进行修改

测试类

public class AdapterDemo {public static void main(String[] args) {// 老版本使用EmeraldVersion emeraldVersion = new EmeraldVersion();emeraldVersion.usePokemon();// 新版本使用NsGame pokemon = new ScarletVersion();pokemon.usePokemon("gbaData");pokemon.usePokemon("nsData");}
}
Go! Rayquaza! (In GBA Version )
Go! Rayquaza! (In Switch Version)
Go! Chikorita (Get In Scarlet Version)

3 扩展

有聪明的读者就会问了:那既然有开闭原则,那如果有新的旧版本或者新版本要加入怎么办呢?

  • 旧版本增加:比如我想把3DS上的宝可梦拿到朱紫用,要怎么办?

如果无视开闭原则,可以这样修改,但其实这种情况更适用于,一开始就告诉了开发者,要适配2个旧版本。

public class DataAdapter implements GbaGame, ThreeDS{GbaGame gbaGame; // 旧世代ThreeDS threeDS; // 3DS世代游戏public DataAdapter(GbaGame gbaGame, ThreeDS threeDS) {this.gbaGame = gbaGame;this.threeDS = threeDS;}@Overridepublic void usePokemon(String dataFormat, String newVersion) {if("gbaData".equals(dataFormat)){gbaGame.usePokemon(dataFormat, newVersion);}else if("threeDS".equals(dataFormat)){threeDS.usePokemon(dataFormat, newVersion);}}
}

所以正确的做法是:为ThreeDS单独再写一个适配器类

public ThreeDsAdapter implements ThreeDS{//...
}
  • 目标接口的新实现:比如剑盾版本也是NS端的,和朱紫写一样的逻辑即可

3 另一个例子

题外话,在学习这个设计模式的时候想到的,在做机器学习的时候,通常有这么个流程:

数据集 -> 数据源 -> 模型 -> …

数据集的格式各不相同,然而,模型的输入是固定的,我们把数据集转换成能够进入模型的过程通常被叫做数据预处理,这是为了让数据集和模型输入的格式适配。比如:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jOAlRVL1-1692546675682)(D:\笔记笔记笔记\设计模式.assets\image-20230820234746268.png)]

每个数据集的分割符不同,那么为了提供给模型一个模型能够接受的格式,就可以使用适配器模式,让数据从csv或者dat格式转换为data_df,即dataframe对象的过程,也就是适配的过程。

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

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

相关文章

IDEA 如何制作代码补丁?IDEA 生成 patch 和使用 patch

什么是升级补丁? 比如你本地修复的 bug,需要把增量文件发给客户,很多场景下大家都需要手工整理修改的文件,并整理好目录,这个很麻烦。那有没有简单的技巧呢?看看 IDEA 生成 patch 和使用 patch 的使用。 介…

一、Kafka概述

目录 1.3 Kafka的基础架构 1.3 Kafka的基础架构 Producer:消息生产者,就是向 Kafka broker 发消息的客户端Consumer:消息消费者,向 Kafka broker 取消息的客户端。Consumer Group(CG):消费者组&…

PyTorch学习笔记(十六)——利用GPU训练

一、方式一 网络模型、损失函数、数据(包括输入、标注) 找到以上三种变量,调用它们的.cuda(),再返回即可 if torch.cuda.is_available():mynn mynn.cuda() if torch.cuda.is_available():loss_function loss_function.cuda(…

SpringMVC之@RequestMapping注解

文章目录 前言一、RequestMapping介绍二、详解(末尾附源码,自行测试)1.RequestMapping注解的位置2.RequestMapping注解的value属性3.RequestMapping注解的method属性4.RequestMapping注解的params属性(了解)5.RequestM…

华为ENSP网络设备配置实战6(简单的链路聚合)

题目要求 1、创建聚合组,添加端口成员 2、PC1网段为vlan10,PC2网段为vlan20 3、LSW1为核心网关设备,正确配置PC网关 4、PC1与PC2互通 解题过程 1.1、 按照拓扑图,各个设备起名 sys (进入系统视图) sy…

TCP协议报文结构

TCP是什么 TCP(传输控制协议)是一种面向连接的、可靠的、全双工的传输协议。它使用头部(Header)和数据(Data)来组织数据包,确保数据的可靠传输和按序传递。 TCP协议报文结构 下面详细阐述TCP…

FRP内网穿透,配置本地电脑作为服务器

FRP内网穿透,配置本地电脑作为服务器 下载FRP服务端客户端 参考链接: https://www.it235.com/实用工具/内网穿透/pierce.html https://www.cnblogs.com/007sx/p/17469301.html 由于没有公网ip,所以尝试内网穿透将本地电脑作为服务器&#xff…

【Mariadb高可用MHA】

目录 一、概述 1.概念 2.组成 3.特点 4.工作原理 二、案例介绍 1.192.168.42.3 2.192.168.42.4 3.192.168.42.5 4.192.168.42.6 三、实际构建MHA 1.ssh免密登录 1.1 所有节点配置hosts 1.2 192.168.42.3 1.3 192.168.42.4 1.4 192.168.42.5 1.5 192.168.42.6 …

(二)结构型模式:7、享元模式(Flyweight Pattern)(C++实例)

目录 1、享元模式(Flyweight Pattern)含义 2、享元模式的UML图学习 3、享元模式的应用场景 4、享元模式的优缺点 5、C实现享元模式的简单实例 1、享元模式(Flyweight Pattern)含义 享元模式(Flyweight&#xff09…

OpenCV笔记之solvePnP函数和calibrateCamera函数对比

OpenCV笔记之solvePnP函数和calibrateCamera函数对比 文章目录 OpenCV笔记之solvePnP函数和calibrateCamera函数对比1.cv::solvePnP2.cv::solvePnP函数的用途和工作原理3.cv::solvePnP背后的数学方程式4.cv::SOLVEPNP_ITERATIVE、cv::SOLVEPNP_EPNP、cv::SOLVEPNP_P3P5.一个固定…

为什么需要单元测试?

为什么需要单元测试? 从产品角度而言,常规的功能测试、系统测试都是站在产品局部或全局功能进行测试,能够很好地与用户的需要相结合,但是缺乏了对产品研发细节(特别是代码细节的理解)。 从测试人员角度而言…

Qt应用开发(基础篇)——纯文本编辑窗口 QPlainTextEdit

一、前言 QPlainTextEdit类继承于QAbstractScrollArea,QAbstractScrollArea继承于QFrame,是Qt用来显示和编辑纯文本的窗口。 滚屏区域基类https://blog.csdn.net/u014491932/article/details/132245486?spm1001.2014.3001.5501框架类QFramehttps://blo…

Elasticsearch复合查询之Boosting Query

前言 ES 里面有 5 种复合查询,分别是: Boolean QueryBoosting QueryConstant Score QueryDisjunction Max QueryFunction Score Query Boolean Query在之前已经介绍过了,今天来看一下 Boosting Query 用法,其实也非常简单&…

Chapter 15: Object-Oriented Programming | Python for Everybody 讲义笔记_En

文章目录 Python for Everybody课程简介Object-oriented programmingManaging larger programsGetting startedUsing objectsStarting with programsSubdividing a problemOur first Python objectClasses as typesObject lifecycleMultiple instancesInheritanceSummaryGlossa…

python基础5——正则、数据库操作

文章目录 一、数据库编程1.1 connect()函数1.2 命令参数1.3 常用语句 二、正则表达式2.1 匹配方式2.2 字符匹配2.3 数量匹配2.4 边界匹配2.5 分组匹配2.6 贪婪模式&非贪婪模式2.7 标志位 一、数据库编程 可以使用python脚本对数据库进行操作,比如获取数据库数据…

Docker 搭建 LNMP + Wordpress(详细步骤)

目录 一、项目模拟 1. 项目环境 2. 服务器环境 3.任务需求 二、Linux 系统基础镜像 三、Nginx 1. 建立工作目录 2. 编写 Dockerfile 脚本 3. 准备 nginx.conf 配置文件 4. 生成镜像 5. 创建自定义网络 6. 启动镜像容器 7. 验证 nginx 四、Mysql 1.…

申请部署阿里云SSL免费证书

使用宝塔自动创建的证书有时候会报NET::ERR_CERT_COMMON_NAME_INVALID,并且每次只能三个月,需要点击续期非常麻烦,容易遗忘。 阿里云免费SSL证书 前往阿里云管理控制台【数字证书管理服务】【SSL证书】,每年20个额度,一…

springBoot 配置文件 flyway 插件相关参数说明

在Spring Boot应用中使用Flyway插件进行数据库迁移时,可以在应用的配置文件中配置相关参数。下面是常用的Flyway配置参数及其说明: flyway.enabled: 是否启用Flyway插件,默认为true,表示启用Flyway插件进行数据库迁移。flyway.ur…

基于Pytorch构建DenseNet网络对cifar-10进行分类

DenseNet是指Densely connected convolutional networks(密集卷积网络)。它的优点主要包括有效缓解梯度消失、特征传递更加有效、计算量更小、参数量更小、性能比ResNet更好。它的缺点主要是较大的内存占用。 DenseNet网络与Resnet、GoogleNet类似&#…

QChart:数据可视化(用图像形式显示数据内容)

1、数据可视化的图形有:柱状/线状/条形/面积/饼/点图、仪表盘、走势图,弦图、金字塔、预测曲线图、关系图、数学公式图、行政地图、GIS地图等。 2、在QT Creator的主页面,点击 欢迎》示例》右侧输入框 输入Chart,即可查看到QChar…