【Kotlin设计模式】Kotlin实现适配器模式

前言


适配器模式(Adapter Pattern)的核心将某个类的接口转换成客户端期望的另一个接口表示,使得客户端能够通过自己期望的接口与不兼容的类进行交互。适配器模式有三种实现方式,分别是类适配器模式对象适配器模式接口适配器模式

我们假设有个视频输出盒子,当前只能接收和输出HDMI信号,现在客户的输入设备只能输出VGA信号,则我们可以通过转换器(要适配的类),将VGA信号转换成HDMI信号做输出。

在这里插入图片描述

在这里插入图片描述


实现


1、类适配器模式

客户目标接口,客户的新设备只能输出VGA信号,无法输出HDMI信号。


/*** 客户目标输入接口*/
interface SourceInput {fun inputVGA(signal:String)
}

Modem盒子只接收且输出HDMI信号,调制后输出给到显示设备进行显示。


/*** 要适配的类*/
open class ModemOutput {fun outputHDMI(signal:String){println("设备输出${signal}给显示设备")}
}

新的输入设备输出VGA模拟信号不满足现在的需求,我们通过定义转换器OutputAdapter,将VGA模拟信号转化成HDMI数字信号进行输出到Modem盒子中。


/*** 转换器*/
class OutputAdapter : ModemOutput(), SourceInput {override fun inputVGA(signal: String) {if ("VGA模拟信号" == signal) {println("【转HDMI信号转换器】>> 接收到了源设备,输入的${signal}")val digital = convertVGAToHDMI(signal)outputHDMI(digital)} else {throw IllegalArgumentException("输入信号错误")}}private fun convertVGAToHDMI(signal: String): String {println("【转HDMI信号转换器】>> 转化器将${signal}转化成HDMI数字信号")return "HDMI数字信号"}
}

客户端


val adapter = OutputAdapter() as SourceInput
adapter.inputVGA("VGA模拟信号")// 【转HDMI信号转换器】>> 接收到了源设备,输入的VGA模拟信号
// 【转HDMI信号转换器】>> VGA转HDMI转化器将VGA模拟信号转化成HDMI数字信号
//  设备输出HDMI数字信号给显示设备

适配器类需要继承ModemOutputJava是单继承模式,所以目标文件必须要是接口。


2、对象适配器模式

对象适配器模式较类适配器模式相比,原来的适配器不再继承要适配的类,将其作为适配器的构造参数传入,把继承解耦。


/*** 要适配的类*/
open class ModemOutput {fun outputHDMI(signal:String){println("设备输出${signal}给显示设备")}
}

/*** 目标接口*/
interface SourceInput {fun inputVGA(signal:String)
}
/*** 转换器*/
class OutputAdapter(output: ModemOutput) : SourceInput {private var mOutput:ModemOutput = outputoverride fun inputVGA(signal: String) {if ("VGA模拟信号" == signal) {println("【转HDMI信号转换器】>> 接收到了源设备,输入的${signal}")val digital = convertVGAToHDMI(analog)mOutput.outputHDMI(signal)} else {throw IllegalArgumentException("输入信号错误")}}private fun convertVGAToHDMI(signal: String): String {println("【转HDMI信号转换器】>> VGA转HDMI转化器将${signal}转化成HDMI数字信号")return "HDMI数字信号"}}

3、接口适配器模式

接口适配器模式适用于目标接口中有多个方法,上面我们举了个目标接口中输入VGA的例子,假如还有DP接口DVI接口的输入,适配器类在实现目标接口时候就要都实现其他的方法,但是客户端输入只有一种,不需要实现全部接口时,如果适配器定义抽象类来实现接口,并且接口中方法空实现,可以灵活解决这个问题。

目标接口新增格式信源输入方法,要适配的类不变。


/*** 目标接口*/
interface SourceInput {fun inputVGA(signal:String)fun inputDP(signal:String)fun inputDVI(signal:String)
}

/*** 要适配的类*/
open class ModemOutput {fun outputHDMI(signal:String){println("设备输出${signal}给显示设备")}
}

新增抽象类,继承源文件ModemOutput、实现目标接口,覆写空方法,不做具体实现。


abstract class OutputAdapter:ModemOutput(),SourceInput {override fun inputDP(signal: String) {TODO("Not yet implemented")}override fun inputDVI(signal: String) {TODO("Not yet implemented")}override fun inputVGA(signal: String) {TODO("Not yet implemented")}
}

客户端只根据自己需要的,具体实现信号输入方法。


val adapter = object : OutputAdapter() {override fun inputDVI(signal: String) {super.inputDVI(signal)println("【转HDMI信号转换器】>> 接收到了源设备,输入的${signal}")val digital = convertSignalToHDMI(signal)outputHDMI(digital)}}private fun convertSignalToHDMI(signal: String): String {when (signal) {"VGA信号" -> {println("【转HDMI信号转换器】>> 转HDMI转化器将${signal}转化成HDMI数字信号")}"DP信号" -> {println("【转HDMI信号转换器】>> 转HDMI转化器将${signal}转化成HDMI数字信号")}"DVI信号" -> {println("【转HDMI信号转换器】>> 转HDMI转化器将${signal}转化成HDMI数字信号")}else ->{throw IllegalArgumentException("输入信号格式不支持")}}return "HDMI数字信号"}

总结


适配器模式可以以类适配器或对象适配器的形式实现,灵活性高。类适配器使用多重继承(在Java中通过接口实现),对象适配器通过组合来实现,原本由于接口不兼容而无法一起工作的类可以协同工作,从而提高了代码的复用性,允许通过引入新的适配器来适应新需求,而无需修改现有的代码,从而实现了开闭原则。

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

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

相关文章

mysql 创建数据库和表,以及对表字段的操作

目录 前言1. 创建数据库2. 选择数据库3. 创建表4. 添加字段5. 修改字段6. 删除字段总结 前言 在MySQL中,你可以通过SQL语句来创建数据库、表,以及在表中添加、修改、删除字段。下面我将分别展示这些操作的示例。 1. 创建数据库 首先,你需要…

3D Tiles的4x4的仿射变换矩阵

前言 项目需要,使用Cesium技术,把STL格式模型加载进去。 一、格式转换 第一步,先将STL文件转换为glTF格式 第二步,将glTF文件转换为3D Tiles格式,使用Cesium ion 二、矩阵整体结构 这个矩阵是一个4x4的仿射变换矩阵&…

3154. 到达第 K 级台阶的方案数

3154. 到达第 K 级台阶的方案数 题目链接:3154. 到达第 K 级台阶的方案数 代码如下: //参考链接:https://leetcode.cn/problems/find-number-of-ways-to-reach-the-k-th-stair/solutions/2782792/liang-chong-fang-fa-ji-yi-hua-sou-suo-zu…

LeetCode题练习与总结:单词搜索Ⅱ--212

一、题目描述 给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。 单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻…

中智科学技术评价研究中心与中企数研究院实现全面合作

8月29日,中智科学技术评价研究中心与《中国企业报》集团数字化发展研究院在北京顺喜山庄成功举办“数字经济GBC生态系统管理平台”项目实施落地座谈会及研究院高层管理集训班,并签署了项目合作协议。此次合作标志着双方将在“数字中国发展战略”的大背景…

人工智能领域正经历模型规模变革,小型语言模型(SLM)崛起,挑战“规模至上”观念。

在人工智能领域,一场关于模型规模的深刻变革正在悄然发生。长久以来,科技巨头们热衷于庞大语言模型(LLM)的开发竞赛,但如今,小型语言模型(SLM)正以其独特的优势逐步崭露头角&#xf…

WordNet介绍——一个英语词汇数据库

传统语义知识库最常见的更新方法是依赖人工手动更新,使用这种更新方法的语义知识库包括最早的 WordNet、FrameNet和 ILD,以及包含丰富内容的 ConceptNet和 DBPedia。此类语义知识库的特点是以单词作为语义知识库的基本构成元素,以及使用预先设…

Linux安装Hadoop(单机版)详细教程

目录 一、JDK安装 1、下载JDK安装包 2、解压下载的JDK安装包 3、移动并重命名JDK包 4、配置Java环境变量 5、验证安装是否成功 二、Hadoop安装 1、下载Hadoop安装包 2、解压Hadoop安装包 3、配置Hadoop环境变量 4、修改配置文件 5、验证Hadoop是否安装成功 三&…

代码随想录——回文子串(Leetcode 647)

题目链接 我的题解(双指针) 思路: 当然,以下是对您提供的代码的解释: class Solution {public int countSubstrings(String s) {// 初始化回文子字符串的数量int count 0;// 遍历字符串的每个字符,使用…

sicp每日一题[1.38]

Exercise 1.38 In 1737, the Swiss mathematician Leonhard Euler published a memoir D e F r a c t i o n i b u s C o n t i n u i s De\ Fractionibus\ Continuis De Fractionibus Continuis, which included a continued fraction expansion for e − 2 e − 2 e−2, wh…

NCH DrawPad Pro for Mac/Win:强大的图像编辑处理软件

NCH DrawPad Pro for Mac/Win是一款功能全面的图像编辑和设计软件,专为Mac和Windows用户设计。它不仅适用于专业设计师,也深受业余爱好者和创意工作者的喜爱。DrawPad Pro凭借其丰富的绘图工具、强大的编辑功能和便捷的模板库,为用户提供了卓…

Android JNI 设置环境变量

setenv 在 Android JNI 中&#xff0c;setenv 是一个 C 标准库函数&#xff0c;用于设置环境变量。你可以通过 JNI 调用这个函数来设置或修改环境变量&#xff1a; #include <jni.h> #include <cstdlib> // For setenvextern "C" JNIEXPORT void JNICA…

OpenCV杂项图像变换(2)线性混合函数blendLinear()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 执行两个图像的线性混合&#xff1a; dst ( i , j ) weights1 ( i , j ) ∗ src1 ( i , j ) weights2 ( i , j ) ∗ src2 ( i , j ) \texttt{…

策略模式+模版方法模式+简单工厂模式混用优化代码复杂分支问题

说明 这篇博客是在复杂场景使用策略和工厂模式代替分支语句升级版&#xff0c;增加了模版方法模式。将支付类的公共逻辑抽取到模板类中&#xff0c;使整个支付逻辑更加灵活&#xff0c;进一步优化了代码结构&#xff0c;提升了软件的可维护性和可读性。 流程图如下 先看一遍流…

.NET 多版本兼容的精美 WinForm UI控件库

目录 前言 项目介绍 项目使用 项目源码 项目案例 项目组件 项目地址 前言 有粉丝小伙伴在后台留言咨询有没有WinForm 控件库推荐&#xff0c;现在就给安排上。 .NET 平台进行 Windows 应用程序开发的我们来说&#xff0c;找一个既美观又实用的 WinForm UI 控件库至关重…

STM32通过ADM3222完成UART转232通信电平转换

1、简介 单片机默认串口输出电平是UART信号,但是在实际项目中经常需要将其转换成232电平,此时就需要ADM3222芯片来完成电平的转换,下面对使用过程进行总结。 2、硬件电路 从上图中可以看到芯片需要对1、18进行配置才能进行工作,通过查阅手册可知,1引脚需要配置低电平,…

Java算法之循环排序(Cyclic Sort)

简介 循环排序&#xff08;Cyclic Sort&#xff09;是一种最小化移动次数的原地排序算法&#xff0c;它利用了数组元素的初始顺序。如果一个元素不在它最终应该在的位置&#xff0c;循环排序会找到这个元素应该在的位置&#xff0c;并将该位置的元素交换过来&#xff0c;直到这…

【react】常用插件收集

Redux状态管理 - reduxjs/toolkit 、 react-redux react-router-dom: 路由 antd-mobile: 移动端组件库 axios:请求插件 dayjs: 时间处理 classnames: class类名处理 Lodash&#xff1a;遍历数据等 地址→ "dependencies": {"reduxjs/toolkit": &quo…

【Ubuntu】Ubuntu 24 配置镜像源

【Ubuntu】Ubuntu 24 配置镜像源 零、起因 最近在虚拟机中安装了个ubuntu-24.04-desktop-amd64&#xff0c;默认是国外的软件源&#xff0c;很慢&#xff0c;故替换到国内。 壹、替换 源地址&#xff08;阿里源&#xff09; https://developer.aliyun.com/mirror/ubuntu …

云计算实训37——Dockerfile的应用+私有仓库的创建与管理

一、文件联合系统 文件联合系统&#xff08;Overlay Filesystem&#xff09;&#xff1a; 是一种允许多个文件系统层叠在一起的文件系统。它通常用于将只读文件系统&#xff08;如基础镜像&#xff09;与可写文件系统&#xff08;如用户的修改&#xff09;结合&#xff0c;形…