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

Go和Java实现适配器模式

Go和Java实现适配器模式

我们通过下面的实例来演示适配器模式的使用,其中,音频播放器设备只能播放 mp3 文件,通过使用一个更高级

的音频播放器来播放 vlc 和 mp4 文件。

1、适配器模式

适配器模式是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的

功能。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡

和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

  • 意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作

    的那些类可以一起工作。

  • 主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对

    象不能满足的。

  • 何时使用:1、系统需要使用现有的类,而此类的接口不符合系统的需要。 2、想要建立一个可以重复使用的

    类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有

    一致的接口。 3、通过接口转换,将一个类插入另一个类系中。(比如老虎和飞禽,现在多了一个飞虎,在不

    增加实体的需求下,增加一个适配器,在里面包容一个虎对象,实现飞的接口。)

  • 如何解决:继承或依赖(推荐)。

  • 关键代码:适配器继承或依赖已有的对象,实现想要的目标接口。

  • 应用实例:1、美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V。 2、JAVA JDK 1.1 提供

    了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的

    Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式。 3、在 LINUX 上运行 WINDOWS 程序。

    4、JAVA 中的 jdbc。

  • 优点:1、可以让任何两个没有关联的类一起运行。 2、提高了类的复用。 3、增加了类的透明度。 4、灵活性

    好。

  • 缺点:1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其

    实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必

    要,可以不使用适配器,而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适

    配者类,而且目标类必须是抽象类。

  • 使用场景:有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。

  • 注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。

  • 适用性:

    你想使用一个已经存在的类,而它的接口不符合你的需求。

    你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协

    同工作。

    (仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接

    口,对象适配器可以适配它的父类接口。

2、Go实现适配器模式

package adapter// ============adapter============
type MediaPlayerAdapter interface {Play(string)
}
package adapterimport "fmt"// ============mp3============
type Mp3Player struct {
}func (mp3Player *Mp3Player) PlayMp3(fileName string) {fmt.Println("Playing Mp3 File: ", fileName)
}
package adapter// ============mp3 adapter============
type Mp3PlayerAdapter struct {Mp3Player
}func (mp3PlayerAdapter *Mp3PlayerAdapter) Play(fileName string) {mp3PlayerAdapter.Mp3Player.PlayMp3(fileName)
}
package adapterimport "fmt"// ============mp4============
type Mp4Player struct {
}func (mp4Player *Mp4Player) PlayMp4(fileName string) {fmt.Println("Playing Mp4 File: ", fileName)
}
package adapter// ============mp4 adapter============
type Mp4PlayerAdapter struct {Mp4Player
}func (mp4PlayerAdapter *Mp4PlayerAdapter) Play(fileName string) {mp4PlayerAdapter.Mp4Player.PlayMp4(fileName)
}
package adapterimport "fmt"// ============vlc============
type VlcPlayer struct {
}func (vlcPlayer *VlcPlayer) PlayVlc(fileName string) {fmt.Println("Playing Vlc File: ", fileName)
}
package adapter// ============vlc adapter============
type VlcPlayerAdapter struct {VlcPlayer
}func (vlcPlayerAdapter *VlcPlayerAdapter) Play(fileName string) {vlcPlayerAdapter.VlcPlayer.PlayVlc(fileName)
}
package constantconst (Mp3 = "mp3"Mp4 = "mp4"Vlc = "vlc"
)
package adapterimport ("proj/constant"
)// ============adapter factory============
type PlayerFactory struct {
}func (playerFactory *PlayerFactory) CreatePlayerAdapter(playerType string) MediaPlayerAdapter {switch playerType {case constant.Mp3:return &Mp3PlayerAdapter{Mp3Player: Mp3Player{}}case constant.Mp4:return &Mp4PlayerAdapter{Mp4Player: Mp4Player{}}case constant.Vlc:return &VlcPlayerAdapter{VlcPlayer: VlcPlayer{}}}return nil
}
package mainimport (. "proj/adapter""proj/constant"
)func main() {// 工厂类playerFactory := PlayerFactory{}// mp3mp3PlayerAdapter := playerFactory.CreatePlayerAdapter(constant.Mp3)// Playing Mp3 File:  qs.mp3mp3PlayerAdapter.Play("qs.mp3")// mp4mp4PlayerAdapter := playerFactory.CreatePlayerAdapter(constant.Mp4)// Playing Mp4 File:  qs.mp4mp4PlayerAdapter.Play("qs.mp4")// vlcvlcPlayerAdapter := playerFactory.CreatePlayerAdapter(constant.Vlc)// Playing Vlc File:  qs.vlcvlcPlayerAdapter.Play("qs.vlc")}

下面再实现一个例子对适配器模式进行介绍。

笔记本通过读卡器去读取 TF 卡和 SD 卡。

package adapter// ============SDCard============
type SDCard interface {ReadSD()
}
package adapterimport "fmt"// ============SDCardImpl============
type SDCardImpl struct {
}func (sDCardImpl *SDCardImpl) ReadSD() {fmt.Println("sdcard read msg!")
}
package adapter// ============TFCard============
type TFCard interface {ReadTF()
}
package adapterimport "fmt"// ============TFCardImpl============
type TFCardImpl struct {
}func (tFCardImpl *TFCardImpl) ReadTF() {fmt.Println("tfcard read msg!")
}
package adapter// ============SDAdapterTF || SDCardImpl============
type SDAdapterTF struct {TFCard
}func (sDAdapterTF *SDAdapterTF) ReadSD() {sDAdapterTF.TFCard.ReadTF()
}
package adapter// ============Computer============
type Computer interface {ReadSD(SDCard)
}
package adapter// ============ComputerImpl============
type ComputerImpl struct {
}func (computerImpl *ComputerImpl) ReadSD(sDCard SDCard) {sDCard.ReadSD()
}
package mainimport . "proj/adapter"func main() {computer := ComputerImpl{}// ============sdcard============// sdcard read msg!computer.ReadSD(&SDCardImpl{})sDAdapterTF := SDAdapterTF{TFCard: &TFCardImpl{}}// ============tfcard============// tfcard read msg!computer.ReadSD(&sDAdapterTF)
}

3、Java实现适配器模式

package com.adapter;// ============adapter============
public interface MediaPlayerAdapter {void play(String fileName);
}
package com.adapter;// ============mp3============
public class Mp3Player {public void playMp3(String fileName){System.out.println("Playing Mp3 File: " + fileName);}
}
package com.adapter;// ============mp3 adapter============
public class Mp3PlayerAdapter implements MediaPlayerAdapter {private Mp3Player mp3Player = new Mp3Player();@Overridepublic void play(String fileName) {mp3Player.playMp3(fileName);}
}
package com.adapter;// ============mp4============
public class Mp4Player {public void playMp4(String fileName){System.out.println("Playing Mp4 File: " + fileName);}
}
package com.adapter;// ============mp4 adapter============
public class Mp4PlayerAdapter implements MediaPlayerAdapter{private Mp4Player mp4Player = new Mp4Player();@Overridepublic void play(String fileName) {mp4Player.playMp4(fileName);}
}
package com.adapter;// ============vlc============
public class VlcPlayer {public void PlayVlc(String fileName){System.out.println("Playing Vlc File: " + fileName);}
}
package com.adapter;// ============vlc adapter============
public class VlcPlayerAdapter implements MediaPlayerAdapter{private VlcPlayer vlcPlayer = new VlcPlayer();@Overridepublic void play(String fileName) {vlcPlayer.PlayVlc(fileName);}
}
package com.adapter;public enum PlayerType {MP3, MP4, VLC;
}
package com.adapter;// ============adapter factory============
public class PlayerFactory {public MediaPlayerAdapter createPlayerAdapter(PlayerType playerType){switch (playerType){case MP3:return new Mp3PlayerAdapter();case MP4:return new Mp4PlayerAdapter();case VLC:return new VlcPlayerAdapter();}return null;}
}
package com.adapter;public class Test {public static void main(String[] args) {MediaPlayerAdapter mediaPlayerAdapter;// 工厂类PlayerFactory playerFactory = new PlayerFactory();// mp3mediaPlayerAdapter = playerFactory.createPlayerAdapter(PlayerType.MP3);// Playing Mp3 File: sq.mp3mediaPlayerAdapter.play("sq.mp3");// mp4mediaPlayerAdapter = playerFactory.createPlayerAdapter(PlayerType.MP4);// Playing Mp4 File: sq.mp4mediaPlayerAdapter.play("sq.mp4");// vlcmediaPlayerAdapter = playerFactory.createPlayerAdapter(PlayerType.VLC);// Playing Vlc File: sq.vlcmediaPlayerAdapter.play("sq.vlc");}
}

下面再实现一个例子对适配器模式进行介绍。

笔记本通过读卡器去读取 TF 卡和 SD 卡。

package com.adapter;// ============SDCard============
public interface SDCard {void readSD();
}
package com.adapter;// ============SDCardImpl============
public class SDCardImpl implements SDCard {@Overridepublic void readSD() {System.out.println("sdcard read msg!");}
}
package com.adapter;// ============TFCard============
public interface TFCard {void readTF();
}
package com.adapter;// ============TFCardImpl============
public class TFCardImpl implements TFCard{@Overridepublic void readTF() {System.out.println("tfcard read msg!");}
}
package com.adapter;// ============SDAdapterTF || SDCardImpl============
public class SDAdapterTF implements SDCard{private TFCard tfCard = new TFCardImpl();@Overridepublic void readSD() {tfCard.readTF();}
}
package com.adapter;// ============Computer============
public interface Computer {void readSD(SDCard sdCard);
}
package com.adapter;// ============ComputerImpl============
public class ComputerImpl implements Computer{@Overridepublic void readSD(SDCard sdCard) {sdCard.readSD();}
}
package com.adapter;public class Test {public static void main(String[] args) {Computer computer = new ComputerImpl();// ============sdcard============SDCard sdCard = new SDCardImpl();// sdcard read msg!computer.readSD(sdCard);// ============tfcard============SDAdapterTF sdAdapterTF = new SDAdapterTF();// tfcard read msg!computer.readSD(sdAdapterTF);}
}

相关文章:

Go和Java实现适配器模式

Go和Java实现适配器模式 我们通过下面的实例来演示适配器模式的使用,其中,音频播放器设备只能播放 mp3 文件,通过使用一个更高级 的音频播放器来播放 vlc 和 mp4 文件。 1、适配器模式 适配器模式是作为两个不兼容的接口之间的桥梁。这种…...

接口相似数据结构复用率高?Apipost这招搞定!

在API设计和开发过程中,存在许多瓶颈,其中一个主要问题是在遇到相似数据结构的API时会产生重复性较多的工作:在每个API中都编写相同的数据,这不仅浪费时间和精力,还容易出错并降低API的可维护性。 为了解决这个问题&a…...

【零基础学Rust | 基础系列 | Hello, Rust】编写并运行第一个Rust程序

文章目录 前言一,创建项目二,两种编译方式1. 使用rustc编译器编译2. 使用Cargo编译 总结 前言 在开始学习任何一门新的编程语言时,都会从编写一个简单的 “Hello, World!” 程序开始。在这一章节中,将会介绍如何在Rust中编写并运…...

代理模式.

前言: 为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 静态代理 抽象角色 : 一般使用接口或者抽象类来实现 真实角色 : 被代理的角色 代理角色 : 代理真实角色 ; 代理真实角色后 , 一…...

BS框架说明

B/S架构 1.B/S框架,意思是前端(Browser 浏览器,小程序、app、自己写的)和服务器端(Server)组成的系统的框架结构 2.B/S框架,也可理解为web架构,包含前端、后端、数据库三大组成部分…...

iOS——Block签名

首先来看block结构体对象Block_layout(等同于clang编译出来的__Block_byref_a_0) #define BLOCK_DESCRIPTOR_1 1 struct Block_descriptor_1 {uintptr_t reserved;uintptr_t size; };#define BLOCK_DESCRIPTOR_2 1 struct Block_descriptor_2 {// requi…...

Flutter 图片选取及裁剪

在开发项目里修改用户头像的功能,涉及到图片选取及裁剪,基本实现步骤如下: 1、pubspec.yaml 添加 image_picker: ^1.0.1 image_cropper: ^4.0.1: dependencies:image_picker: ^1.0.1image_cropper: ^4.0.1flutter:sdk: flutter…...

C语言每日一题:11.《数据结构》链表分割。

题目一: 题目链接: 思路一:使用带头链表 1.构建两个新的带头链表,头节点不存储数据。 2.循环遍历原来的链表。 3.小于x的尾插到第一个链表。 4.大于等于x尾插到第二个链表。 5.进行链表合并,注意第二个链表的尾的下一…...

记一次Oracle归档日志异常增长问题的排查过程

Oracle归档日志是Oracle数据库的重要功能,用于将数据库的重做日志文件(Redo Log)保存到归档日志文件(Archive Log)中。归档日志的作用是提供数据库的备份和恢复功能,以及支持数据库的持续性和数据完整性。 …...

Java设计模式——类之间的关系

1.继承关系(泛化) 类与子类的关系,指一个类继承另外的一个类。 2.实现关系 一个类可以实现多个接口,实现所有接口的功能。 3.依赖关系 类B作为类A方法中的局部变量或者参数出现,表示A依赖B。 4.关联关系 类B作为类A中的成员变量出现&#…...

Dockerfile构建Redis镜像

建立工作目录 [rootlocalhost ~]# mkdir redis [rootlocalhost ~]# cd redis/ 编写Dockerfile文件 [rootlocalhost redis]# vim Dockerfile FROM centos:7 MAINTAINER dddd <dddd163.com> RUN yum -y install epel-release && yum -y install redis RUN sed -i …...

C高级DAY2

1.思维导图 2. 递归实现&#xff0c;输入一个数&#xff0c;输出这个数的每一位 递归实现&#xff0c;输入一个数&#xff0c;输出这个数的二进制c 写一个脚本&#xff0c;包含以下内容&#xff1a; 显示/etc/group文件中第五行的内容创建目录/home/ubuntu/copy切换工作路径到…...

Linux 服务管理

在Linux上&#xff0c;服务管理是指对系统中运行的服务进行启动、停止、重启、监控和配置的过程。以下是一些常用的Linux服务管理工具和命令&#xff1a; 1. systemctl&#xff1a;systemctl 是一个Linux系统服务管理工具&#xff0c;可以管理Systemd初始化系统的服务。常见的…...

问题记录 1 页面初始化触发el-form必填校验

bug: 先编辑table某条数据,然后关闭,再去新增的时候就会触发el-form必填校验, 网上搜了一下是因为 rules里触发的方式为change时,赋值数据的格式不一致导致触发校验, 最后也没找到正确的解决方法, 只能用很low方式去解决了 方案1. 把trigger改为 blur 失焦后触发 方案2. 初始化…...

后端整理(JVM、Redis、反射)

1. JVM 文章仅为自身笔记 详情查看一篇文章掌握整个JVM&#xff0c;JVM超详细解析&#xff01;&#xff01;&#xff01; 1.1 什么是JVM jvm是Java虚拟机 1.2 Java文件的编译过程 程序员编写代码形成.java文件经过javac编译成.class文件再通过JVM的类加载器进入运行时数据…...

1. CUDA中的grid和block

1. CUDA中的grid和block基本的理解 Kernel: Kernel不是CPU&#xff0c;而是在GPU上运行的特殊函数。你可以把Kernel想象成GPU上并行执行的任务。当你从主机&#xff08;CPU&#xff09;调用Kernel时&#xff0c;它在GPU上启动&#xff0c;并在许多线程上并行运行。 Grid: 当你…...

宝存科技企业级固态硬盘解决方案助力企业应用性能提升

企业级固态硬盘解决方案的核心 企业级固态硬盘市场具有产品附加值高、同时进入门槛高的特征&#xff0c;由于国内外巨头和初创企业竞争依然激烈。想要在竞争中脱颖而出&#xff0c;根本还是要靠产品本身的品质和厂商实力。 企业级固态硬盘适用于各类企业应用场景 企业级固态硬盘…...

《练习100》31~35

题目31 # press any key to change color,do you want to try it. Please hurry up!# 第一种使用颜色配置输出 # 向终端输出彩色字符&#xff0c;色彩的设置由目标终端文字系统和转义字符控制&#xff0c;与具体的编程语言无关 # 参数名称 参数值 # 文字效果 0&#xff1a;终端…...

额外题目第4天|132 673 841 127 684 657

132 我发现困难题往往是在中等题的基础上再多了一步 分割最少次数的回文子串 这道题就是在之前动态规划法找回文子串 (leetcode第5题) 的基础上更多 这题还是用动规来写 思路参考代码随想录 dp数组表示的意义是从0到i最少切割的次数 递推公式是 取0到i中间值 j 如果从 j1到…...

HTTP 状态码的分类和含义

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;状态码是由服务器向客户端传输的 HTTP 响应中的一个三位数字代码。它们提供了关于请求的处理状态和结果的信息。以下是一些常见的 HTTP 状态码及其含义&#xff1a; 1xx 信息响应&#xff1a;指示服务器已收到请求&…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...

2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版

1.题目描述 2.思路 当前的元素可以重复使用。 &#xff08;1&#xff09;确定回溯算法函数的参数和返回值&#xff08;一般是void类型&#xff09; &#xff08;2&#xff09;因为是用递归实现的&#xff0c;所以我们要确定终止条件 &#xff08;3&#xff09;单层搜索逻辑 二…...