适配器模式来啦

网上的大多数的资料中适配器模式和代理模式都是紧挨着进行介绍的,为什么呢???

是因为适配器模式和代理模式有太多的相似之处,可以进行联动记忆但是也要做好区分。

在菜鸟教程中,适配器模式的定义是作为两个不兼容接口之间的桥梁使其变得可兼容;从代码层面来解释就是有一个接口需要实现,但是现有的对象都不满足,需要对对象进行适配(就是加一层伪装)

适配器模式总共有三种,默认适配器模式,对象适配器模式,类适配器模式

一、默认适配器模式

用 Appache commons-io 包中的 FileAlterationListener 做例子,此接口定义了很多的方法,用于对文件或文件夹进行监控,一旦发生了对应的操作,就会触发相应的方法。

public interface FileAlterationListener {void onStart(final FileAlterationObserver observer);void onDirectoryCreate(final File directory);void onDirectoryChange(final File directory);void onDirectoryDelete(final File directory);void onFileCreate(final File file);void onFileChange(final File file);void onFileDelete(final File file);void onStop(final FileAlterationObserver observer);
}

此接口的一大问题是抽象方法太多了,如果我们要用这个接口,意味着我们要实现每一个抽象方法,如果我们只是想要监控文件夹中的文件创建文件删除事件,可是我们还是不得不实现所有的方法,很明显,这不是我们想要的。

所以,我们需要下面的一个适配器,它用于实现上面的接口,但是所有的方法都是空方法,这样,我们就可以转而定义自己的类来继承下面这个类即可

public class FileAlterationListenerAdaptor implements FileAlterationListener {public void onStart(final FileAlterationObserver observer) {}public void onDirectoryCreate(final File directory) {}public void onDirectoryChange(final File directory) {}public void onDirectoryDelete(final File directory) {}public void onFileCreate(final File file) {}public void onFileChange(final File file) {}public void onFileDelete(final File file) {}public void onStop(final FileAlterationObserver observer) {}
}

我们可以定义以下类,我们仅仅需要实现我们想实现的方法就可以了

public class FileMonitor extends FileAlterationListenerAdaptor {public void onFileCreate(final File file) {// 文件创建doSomething();}public void onFileDelete(final File file) {// 文件删除doSomething();}
}

默认适配器模式是三种适配器中最简单的一种模式,整体是为了单一职责原则,过滤掉本身不需要的能力,防止给调用方造成空能力的假象

二、对象适配器模式

大家都看过电影聊斋画皮吧,其中九霄美狐小唯因王家军首领王生勇猛英俊对其萌生爱意,想取代王生妻子佩蓉的地位。但是小唯是狐狸啊,想要和王生在一起至少得变成一个人吧(至少看起来是人),所以小唯披上了一个绝色美女的皮用于迷惑王生,使得狐狸小唯的行为在王生等人看来和自己没什么区别。

举个🌰

public interface Fox {public void walk(); // 走路public void eat(); // 吃饭
}public interface Person {public void walk(); // 走路public void eat(); // 吃饭
}public class XiaoWei implements Fox {public void walk() {System.out.println("狐狸走路,四条腿");}public void eat() {System.out.println("狐狸吃饭");}
}public class WangSheng implements Person {public void walk() {System.out.println("人走路,两条腿");}public void eat() {System.out.println("人吃饭");}
}

人接口有 walk() 和 eat() 两个方法,狐狸 Fox 如果要冒充人, walk() 和 eat() 两个方法是现成的,但是本质上是不同的(狐狸实现Fox接口 , 人实现Person接口),所以需要适配让狐狸小唯看起来像人

这里相当于祭炼法器了(FoxAdapter)

// 毫无疑问,首先,这个适配器肯定需要 implements Person,这样才能当做人来看
public class FoxAdapter implements Person {Fox fox;// 构造方法中需要一个狐狸的实例,此类就是将这只狐狸适配成人来用public FoxAdapter(Fox fox) {this.fox = fox;}// 实现人的走路方法@Overridepublic void walk() {// 内部其实是一只狐狸的走路fox.walk();}@Overridepublic void eat() {// 内部其实是一只狐狸的吃饭    fox.eat();}
}

然后就是使用法器(FoxAdapter)

public static void main(String[] args) {// 有一只美狐小唯Fox xiaowei = new XiaoWei();// 成功将美狐小唯适配成人Person person = new FoxAdapter(xiaowei);...
}

用一个小小的图来加深一下理解

adapter-1

三、类适配器模式

小心,看图😏

adapter-1

 看到这个图,大家应该很容易理解的吧,通过继承的方法,适配器自动获得了所需要的大部分方法,在适配器中包装一下不就妥妥的。这个时候,客户端使用更加简单,直接 Target t = new SomeAdapter(); 就可以了

四、适用场景

适配器模式主要用于查缺补漏阶段而不是设计阶段。当出现两个接口不兼容的问题才会使用该设计模式,而不是一开始就设计成这样的模式。

如果想要对多类对象和对象的能力进行组合叠加可使用桥接模式

五、总结

文章中一开始就说过代理模式和适配器模式是有相似的,get到了吗🤔

代理模式和适配器模式(对象)都是以对象组合的方式进行代理和适配,不过不同的是代理相当于游戏中给游戏角色上外挂,只是对原有能力的增强。例如刺激战场的自动瞄准挂,原本角色就能开枪干人只是中不中的问题,加了外挂增强开枪干人的命中率并没有改变本质行为。适配模式则是本质上的改变,别人是开枪干人,结果你适配成开战斗机扫射。

立秋 渐寒 添衣 勿病 安好

五、引用

1、Java 设计模式 - 掘金

2、适配器模式 | 菜鸟教程

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

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

相关文章

PyQt学习笔记-Windows系统版本兼容问题踩坑记录

1 Pyinstaller打包的exe在Win10上可以使用&#xff0c;在Win7上缺提示找不到dll。 错误信息&#xff1a; Traceback (most recent call last): File "main.py", line 4, in <module> ImportError: DLL load failed while importing QtWidgets: 找不到指定的…

【大数据】Flink 从入门到实践(一):初步介绍

Flink 从入门到实践&#xff08;一&#xff09;&#xff1a;初步介绍 Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于在 无边界 和 有边界 数据流上进行 有状态 的计算。Flink 能在所有常见集群环境中运行&#xff0c;并能以内存速度和任意规模进行计算。 1.架构 1…

docker中的jenkins之流水线构建

docker中的jenkins之流水线构建项目 1、用node这种方式&#xff08;因为我用pipeline方式一直不执行&#xff0c;不知道为什么&#xff09; 2、创建项目 创建两个参数&#xff0c;一个是宿主端口号&#xff0c;一个是docker中的端口号 3、使用git项目中的Jenkinsfile 4、编写…

区块链学习6-长安链部署:如何创建特定共识节点数和同步节点数的链

正常prepare的时候只支持4 7 13 16个节点个数&#xff0c;想要创建10个节点&#xff0c;其中5个是共识节点&#xff0c;如何实现&#xff1f; 1. 注释掉prepare.sh的这几行&#xff1a; 2. 修改 crytogen的模板文件&#xff1a; 如果是cert模式&#xff1a;chainmaker-crypt…

《使用 VMware 在 Windows 上搭建 Linux 系统的完整指南》

《使用 VMware 在 Windows 上搭建 Linux 系统的完整指南》 1、准备工作1.1 安装 VMware 软件1.2 下载 Linux 发行版镜像文件1.3 安装SSH工具 2、创建新的虚拟机2.1 VMware页面2.2 打开VMware页面并点击创建新的虚拟机&#xff0c;选择自定义2.3 选择系统兼容性&#xff0c;默认…

嵌入式面试刷题(day3)

文章目录 前言一、怎么判断两个float是否相同二、float数据可以移位吗三、数据接收和发送端大小端不一致怎么办四、怎么传输float类型数据1.使用联合进行传输2.使用字节流3.强制类型转换 总结 前言 本篇文章我们继续讲解嵌入式面试刷题&#xff0c;给大家继续分享嵌入式中的面…

compile_and_runtime_not_namespaced_r_class_jar\debug\R.jar: 另一个程序正在使用

问题情况&#xff1a; run App的时候&#xff0c;提示该文件被占用 想要clean Project&#xff0c;还是提示该文件被占用&#xff0c;这个文件和连带的文件夹都无法被删除。 方法1&#xff1a; AndroidStudio下方的terminal&#xff08;没有这个窗口的话&#xff0c;从上面的…

Android Glide MemorySizeCalculator计算值,Kotlin

Android Glide MemorySizeCalculator计算值,Kotlin for (i in 100..1000 step 50) {val calculator MemorySizeCalculator.Builder(this).setMemoryCacheScreens(i.toFloat()).setBitmapPoolScreens(i.toFloat()).setMaxSizeMultiplier(0.8f).setLowMemoryMaxSizeMultiplier(0…

Fastjson 使用指南

文章目录 Fastjson 使用指南0 简要说明为什么要用JSON&#xff1f;用JSON的好处是什么&#xff1f;为什么要用JSON&#xff1f;JSON好处 1 常用数据类型的JSON格式值的范围 2 快速上手2.1 依赖2.2 实体类2.3 测试类 3 常见用法3.1 序列化操作核心操作对象转换为JSON串list转换J…

Java课题笔记~ Spring 概述

Spring 框架 一、Spring 概述 1、Spring 框架是什么 Spring 是于 2003 年兴起的一个轻量级的 Java 开发框架&#xff0c;它是为了解决企业应用开发的复杂性而创建的。Spring 的核心是控制反转&#xff08;IoC&#xff09;和面向切面编程&#xff08;AOP&#xff09;。 Spring…

canal 嵌入式部署 监听binlog

canal 嵌入式部署 背景技术选型canal原理用途嵌入式代码实现引入pom引入工具pommain方法引入常量定义install方法buildCanal方法pull方法printSummaryprintEntry2 总结谢谢 背景 最近发现一个需求,需要监听mysql 数据库里的数据变动, 但由于架构方面的原因, 只能做成单体嵌入式…

如何优化测试用例?

在我们日常测试工作中&#xff0c;编写测试用例往往花费较多时间&#xff0c;而且设计的测试用例冗杂和不完整&#xff0c;从而造成用例执行检查不完整&#xff0c;效率低下&#xff0c;不能及时发现项目缺陷。 因此提高测试用例编写和执行效率迫在眉睫&#xff0c;一般来说&am…

python之prettytable库的使用

文章目录 一 什么是prettytable二 prettytable的简单使用1. 添加表头2. 添加行3. 添加列4. 设置对齐方式4. 设置输出表格样式5. 自定义边框样式6. 其它功能 三 prettytable在实际中的使用 一 什么是prettytable prettytable是Python的一个第三方工具库&#xff0c;用于创建漂亮…

Endnote 具体期刊格式检索和下载方法——以nature期刊参考文献格式检索和下载为例

Endnote 具体期刊格式检索和下载方法——以nature期刊参考文献格式检索和下载为例 在外文文章写作时候&#xff0c;有时为了提高写作效率&#xff0c;会用到Endnote文献引用功能。然而&#xff0c;有时可能没有现成的参考文献格式&#xff0c;此时&#xff0c;比较快捷的方式&…

【云原生】kubernetes控制器deployment的使用

目录 ​编辑 1 Controller 控制器 1.1 什么是 Controller 1.2 常见的 Controller 控制器 1.3 Controller 如何管理 Pod 2 Deployment 2.1 创建 deployment 2.2 查看 deployment 2.3 扩缩 deployment 2.4 回滚 deployment 2.5 删除 deployment 1 Controller 控制器 …

【设计模式】观察者模式

什么是观察者模式&#xff1f; 观察者模式&#xff08;又被称为发布-订阅&#xff08;Publish/Subscribe&#xff09;模式&#xff0c;属于行为型模式的一种&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态…

【Git】标签管理与Git Flow模型

目录 一、操作标签 二、推送标签 三、删除标签 四、Git Flow模型分支设计 一、操作标签 git tag # 查看有哪些标签 git tag [name] # 给最近一次commit打标签 git tag [name] [commitID] #给指定的commit打标签 git tag -a [name] -m desc # 打标签并添加描述 二、推送标…

Titanic细节记录一

目录 chunker header index_col names Series与DataFrame的区别 df.columns del和drop的区别 reset_index loc与iloc的区别 不同的排序方式 sort_values sort_index DataFrame相加 describe函数查看数据基本信息 查看多个列的数据时使用列表 处理缺失值的几种思路 …

Java密码学

密码学 1.1 密码学基本概念 密码在我们的生活中有着重要的作用&#xff0c;那么密码究竟来自何方&#xff0c;为何会产生呢&#xff1f; 密码学是网络安全、信息安全、区块链等产品的基础&#xff0c;常见的非对称加密、对称加密、散列函数等&#xff0c;都属于密码学范畴。…

【ARM Cache 系列文章 9 -- ARM big.LITTLE技术】

文章目录 big.LITTLE 技术背景big.LITTLE 技术详解big.LITTLE 硬件要求 big.LITTLE 软件模型CPU MigrationGlobal Task SchedulingGlobal Task Scheduling比CPU Migration的优势 转自&#xff1a;https://zhuanlan.zhihu.com/p/630981648 如有侵权&#xff0c;请联系删除 big.L…