【地铁上的设计模式】--结构型模式:适配器模式
前面几篇文章我们学习了创建型模式,从本篇文章开始,我们将学习结构型模式。
什么是结构型模式
结构型模式是一种设计模式,它描述了如何将类或对象结合在一起形成更大的结构,以提供新的功能或实现更复杂的行为。结构型模式包括以下几种:
- 适配器模式(Adapter Pattern):将一个类的接口转换成客户端所期望的另一种接口,从而让原本因接口不兼容而不能一起工作的类能够一起工作。
- 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。
- 组合模式(Composite Pattern):将对象组合成树形结构以表示“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
- 装饰器模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就增加功能而言,装饰器模式比生成子类更为灵活。
- 外观模式(Facade Pattern):为子系统中的一组接口提供一个一致的界面,定义了一个高层接口,使得子系统更加容易使用。
- 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象。
- 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。
这些结构型模式都是为了解决不同的设计问题而产生的,具有一定的适用范围和场景。在实际开发中,我们可以根据具体的需求来选择使用哪种结构型模式,以达到最优的设计效果。
首先,我们来学习一下适配器模式
什么是适配器模式
适配器模式是一种结构型设计模式,用于将一个类的接口转换成客户端所期望的另一种接口。在现实生活中,适配器是一个常见的概念,比如我们去旅游时需要一个转换器适配器将电器从国内电压适配到国外电压。
在软件开发中,适配器模式也是经常用到的。它可以帮助我们在不修改已有代码的情况下,实现不同类之间的互相适配,从而提高代码的复用性和可维护性。
适配器模式包含三个角色:目标接口、适配器和被适配者。目标接口是客户端所期望的接口,适配器实现了目标接口,并持有被适配者的引用,通过调用被适配者的接口实现目标接口。被适配者是原本存在的类,但是其接口与目标接口不兼容。
适配器模式有两种实现方式:类适配器和对象适配器。类适配器通过继承被适配者类和实现目标接口,来实现适配器。对象适配器则通过持有被适配者的引用,在适配器中实现目标接口来实现适配器。
适配器模式的优点在于可以将不兼容的接口进行适配,使得现有代码得到复用,而不需要改变现有代码。同时,适配器模式也可以降低类之间的耦合度,提高代码的灵活性和可维护性。
适配器模式也有一些缺点。首先,适配器会增加系统的复杂性,增加代码的数量和维护成本。其次,适配器模式不适合在设计初期使用,而应该是在已有代码需要进行接口调整时使用。
总的来说,适配器模式是一种实用性很强的设计模式,可以帮助我们在不修改已有代码的情况下实现接口的适配,提高代码的复用性和可维护性。
如何实现适配器模式
实现适配器模式的一般步骤如下:
- 定义目标接口:即需要适配的接口,也就是系统需要使用的接口。
- 定义适配器:实现目标接口,并持有适配者对象的引用。
- 定义适配者:即需要被适配的对象,其原本的接口与系统需要使用的接口不兼容。
- 在适配器中实现目标接口方法:在适配器中将目标接口方法的调用转换为对适配者的调用,以达到适配的目的。
- 在客户端中使用适配器:将适配器对象传递给客户端,由客户端调用目标接口方法。
具体实现步骤可能会因为编程语言和实际应用场景而有所不同,但以上是适配器模式的一般实现步骤。
Java实现
下面是Java实现适配器模式的示例代码:
首先,定义一个目标接口(Target):
public interface Target {void request();
}
然后,定义一个需要适配的类(Adaptee):
public class Adaptee {public void specificRequest() {System.out.println("Adaptee specific request");}
}
接下来,实现一个适配器(Adapter),让它实现目标接口(Target):
public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}public void request() {adaptee.specificRequest();}
}
适配器(Adapter)类持有一个需要适配的对象(Adaptee)的引用,在实现目标接口的方法时,通过调用该对象的特定方法实现适配。
最后,使用适配器模式将需要适配的类(Adaptee)适配到目标接口(Target)上:
public class Client {public static void main(String[] args) {Adaptee adaptee = new Adaptee();Target target = new Adapter(adaptee);target.request();}
}
在客户端代码中,实例化需要适配的类(Adaptee),然后将其通过适配器(Adapter)适配到目标接口(Target)上,实现了对需要适配的类的调用。以上就是适配器模式在Java中的实现步骤和示例代码。
C#实现
在 C# 中,适配器模式的实现与 Java 类似。下面是一个简单的示例:
// 目标接口
public interface ITarget {void Request();
}// 适配者接口
public class Adaptee {public void SpecificRequest() {Console.WriteLine("Adaptee.SpecificRequest() called.");}
}// 类适配器
public class Adapter : Adaptee, ITarget {public void Request() {SpecificRequest();}
}// 对象适配器
public class ObjectAdapter : ITarget {private Adaptee _adaptee;public ObjectAdapter(Adaptee adaptee) {_adaptee = adaptee;}public void Request() {_adaptee.SpecificRequest();}
}// 客户端代码
static void Main(string[] args) {// 类适配器ITarget target1 = new Adapter();target1.Request();// 对象适配器Adaptee adaptee = new Adaptee();ITarget target2 = new ObjectAdapter(adaptee);target2.Request();
}
在类适配器中,适配器类继承了适配者类,并实现了目标接口。在对象适配器中,适配器类将适配者对象作为其成员,并实现了目标接口。两种实现方式的结果是相同的,都可以将适配者的接口转换成目标接口,从而使得客户端可以通过目标接口调用适配者的方法。
需要注意的是,在 C# 中,接口和抽象类都可以作为适配器的目标接口。由于 C# 不支持多重继承,因此无法像 Java 一样通过继承多个接口来实现适配器模式。但是,C# 支持接口的默认实现,这使得我们可以实现一个默认适配器类,用来适配目标接口的默认行为。
总结
适配器模式通过包装一个不兼容的对象,将其转换为与另一个对象兼容的形式。它提供了一种将新代码与现有代码集成的方法,同时也可以减少代码的重复。在实际应用中,适配器模式可以用于集成不同的系统和组件,使它们能够无缝地协同工作。它的缺点是增加了代码的复杂性,因为需要额外的适配器类来进行转换。在设计时需要考虑到接口的扩展和变化,以免影响适配器的使用。适配器模式在实际的软件开发中非常有用,特别是在集成不同的系统或组件时。
相关文章:
【地铁上的设计模式】--结构型模式:适配器模式
前面几篇文章我们学习了创建型模式,从本篇文章开始,我们将学习结构型模式。 什么是结构型模式 结构型模式是一种设计模式,它描述了如何将类或对象结合在一起形成更大的结构,以提供新的功能或实现更复杂的行为。结构型模式包括以…...
重大剧透:你不用ChatGPT,它砸你饭碗
早晨看到路透社报道,盖茨说,与其争论技术的未来,不如专注于如何更好地利用人工智能。 这可能是他对马斯克他们呼吁暂停AI研发6个月的一种回应吧。 有种古语说:天下大势,浩浩汤汤,顺之者昌,逆之者…...
状态机模式
状态模式 状态模式定义:使用场景角色定义1. State一抽象状态角色2. ConcreteState一-具体状态角色3. Context--环境角色 需求背景1. 订单状态抽象类2. 定义订单具体状态类并集成基类(抽象类)2.1 订单创建状态2.2 订单已支付状态2.3 订单已发货状态2.4 订…...
瑞吉外卖:后台系统登录功能
文章目录 需求分析代码开发创建实体类导入返回结果类Rcontroller、service与mapperlogin.html 需求分析 点击登录按钮后,浏览器以POST方式向employee/login提交username和password,服务器经过处理后向浏览器返回某种格式的数据,其中包含&…...
Linux拓展:链接库
一.说明 本篇博客介绍Linux操作系统下的链接库相关知识,由于相关概念已在Windows下链接库一文中介绍,本篇博客直接上操作。 二.静态链接库的创建和使用 1.提前看 这里主要介绍的是C语言的链接库技术,而在Linux下实现C语言程序,…...
基于.Net开发的、支持多平台、多语言餐厅点餐系统
今天给大家推荐一套支持多平台、多语言版本的订单系统,适合餐厅、酒店等场景。 项目简介 这是基于.Net Framework开发的,支持手机、平板、PC等平台、多语言版本开源的点餐系统,非常适合餐厅、便利店、超市、酒店等,该系统基础功…...
Windows系统SSL/TLS安全协议介绍
支持安全加密的https底层使用的就是SSL/TLS,在发起https请求之前需要先建立TCP连接,之后再进行SSL/TLS协议协商,协商通过后才能发起https请求。本文将详细介绍SSL/TLS协议相关的内容。 之前在项目中就出现过客户端SSL/TLS版本过低,导致向服务器发起连接时被服务器拒绝的问题…...
ovs-vsctl 命令详解
ovs-vsctl 命令详解 网桥Bridge 创建 Bridge ovs-vsctl add-br br0 删除 Bridge ovs-vsctl del-br br0 列出 Bridge ovs-vsctl list-br 显示详情 ovs-vsctl show 端口 Port 添加端口 ovs-vsctl add-port br0 p1 其中br0 为上面添加的bridge p1可以是物理端口或者vN…...
具备“记忆”功能的VBA目录选择器
大家使用任意一款浏览器(例如:Chrome、Edge)下载文件时,如果【另存为】对话框选择C:\Download,那么下次再次使用【另存为】功能,对话框默认显示C:\Download,而不是根目录。 在VBA开发中调用目录…...
electron入门 | 手把手带electron项目初始化
Electron是一个基于Chromium和 Node.js,可以使用 HTML、CSS和JavaScript构建跨平台应用的技术框架,兼容 Mac、Windows 和 Linux。 目录 1.了解electron 2.开发环境 3.初始化 采坑插曲: 1.了解electron Electron 可以让你使用纯 JavaScrip…...
力扣解法汇总2423. 删除字符使频率相同
目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣 描述: 给你一个下标从 0 开始的字符串 word ,字符串只包含小写英文字母。你…...
【超算/先进计算学习】日报8
目录 今日已完成任务列表遇到的问题及解决方案任务完成详细笔记阶段一阶段二阶段三阶段四 对自己的表现是否满意简述下次计划其他反馈 今日已完成任务列表 超算/高性能计算总结 遇到的问题及解决方案 无 任务完成详细笔记 阶段一 在学习的第一阶段,我们首先对需要…...
《LearnUE——基础指南:上篇—2》——GamePlay架构之Level和World
目录 听说世界是由多个Level组成的 1.2.1 引言 1.2.2 建造大陆(ULevel) 1.2.3构建世界(World) 1.2.4总结 听说世界是由多个Level组成的 1.2.1 引言 上小节谈到Actor和Component的关系,UE利用Actor的概念组成了世…...
IDEA部署tomcat项目
文章目录 只是部署一下看到这里即可war和war exploded的区别warwar exploded update的动作update resourcesupdate classes and resourcesredeployrestart server 解决了拿到了一个tomcat项目后如何将它部署到IDEA里面的问题。 file->open 选中pom.xml并open as project …...
IAM角色
Identity-based policy,它关联到特定的User/Role/Group上,指定这些主体能对哪些资源进行怎样的操作 Resource-based policy,它关联到具体的AWS资源上,指定哪些主体可以对这个资源做怎样的操作 aws受信任关系视为aws服务可以实现&a…...
【VAR | 时间序列】以美国 GDP 和通货膨胀数据为例的VAR模型简单实战(含Python源代码)
以美国 GDP 和通货膨胀数据为例: 1. 数据集 下载数据我们需要从 FRED 数据库下载美国 GDP 和通货膨胀数据,并将它们存储在 CSV 文件中。可以在 FRED 网站(https://fred.stlouisfed.org/)搜索并下载需要的数据。在这里࿰…...
常用的设计模式之二(行为型模式)
文章目录 观察者模式模板模式 观察者模式 观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有观察者都会收到通知并进行相应的处理。 观察者…...
MYSQL基本操作(增删改查)
数据库的列类型 int:整型 用于定义整数类型的数据 float:单精度浮点4字节32位 准确表示到小数点后六位 double:双精度浮点8字节64位 char:固定长度的字符类 用于定义字符类型数据&…...
双周赛103(模拟、网格图BFS、树状数组)
文章目录 双周赛103[6406. K 个元素的最大和](https://leetcode.cn/problems/maximum-sum-with-exactly-k-elements/)模拟 [6405. 找到两个数组的前缀公共数组](https://leetcode.cn/problems/find-the-prefix-common-array-of-two-arrays/)模拟 [6403. 网格图中鱼的最大数目](…...
【数据结构】二叉树(详细)
二叉树 1.树1.1定义1.2基本术语1.3树形结构和线性结构1.4树的存储结构1.4.1双亲表示法1.4.2孩子兄弟表示法 2.二叉树2.1定义2.2特殊二叉树2.3性质2.4存储结构2.4.1顺序存储2.4.2链式存储结构 3.二叉树的基本操作3.1前序遍历(先序遍历)3.2中序遍历3.3后序…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
