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

设计模式(十三)----结构型模式之桥接模式

1 概述

现在有一个需求,需要创建不同的图形,并且每个图形都有可能会有不同的颜色。我们可以利用继承的方式来设计类的关系:

我们可以发现有很多的类,假如我们再增加一个形状或再增加一种颜色,就需要创建更多的类。

试想,在一个有多种可能会变化的维度的系统中,用继承方式会造成类爆炸,扩展起来不灵活。每次在一个维度上新增一个具体实现都要增加多个子类。为了更加灵活的设计系统,我们此时可以考虑使用桥接模式。

定义:

将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

2 结构

桥接(Bridge)模式包含以下主要角色:

  • 抽象化(Abstraction)角色 :定义抽象类,并包含一个对实现化对象的引用。下面中的OperatingSystem

  • 扩展抽象化(Refined Abstraction)角色 :是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。

  • 实现化(Implementor)角色 :定义实现化角色的接口,供扩展抽象化角色调用。下面中的VidoeFile接口

  • 具体实现化(Concrete Implementor)角色 :给出实现化角色接口的具体实现。

3 案例

【例】视频播放器

需要开发一个跨平台视频播放器,可以在不同操作系统平台(如Windows、Mac、Linux等)上播放多种格式的视频文件,常见的视频格式包括RMVB、AVI、WMV等。该播放器包含了两个维度,适合使用桥接模式。

类图如下:

代码如下:

//视频文件   实现化角色
public interface VideoFile {void decode(String fileName);
}
​
//avi文件  具体实现化角色
public class AVIFile implements VideoFile {public void decode(String fileName) {System.out.println("avi视频文件:"+ fileName);}
}
​
//rmvb文件  具体实现化角色
public class REVBBFile implements VideoFile {
​public void decode(String fileName) {System.out.println("rmvb文件:" + fileName);}
}
​
//操作系统版本  抽象角色
public abstract class OperatingSystemVersion {
​protected VideoFile videoFile;
​public OperatingSystemVersion(VideoFile videoFile) {this.videoFile = videoFile;}
​public abstract void play(String fileName);
}
​
//Windows版本  扩展抽象化角色
public class Windows extends OperatingSystem {
​public Windows(VideoFile videoFile) {super(videoFile);}
​public void play(String fileName) {videoFile.decode(fileName);}
}
​
//mac版本  扩展抽象化角色
public class Mac extends OperatingSystemVersion {
​public Mac(VideoFile videoFile) {super(videoFile);}
​public void play(String fileName) {videoFile.decode(fileName);}
}
​
//测试类
public class Client {public static void main(String[] args) {OperatingSystem os = new Windows(new AVIFile());os.play("战狼3");}
}

好处:

  • 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。

    如:如果现在还有一种视频文件类型wmv,我们只需要再定义一个类实现VideoFile接口即可,其他类不需要发生变化。

  • 实现细节对客户透明

4 使用场景

  • 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。

  • 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。

  • 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。

相关文章:

设计模式(十三)----结构型模式之桥接模式

1 概述 现在有一个需求,需要创建不同的图形,并且每个图形都有可能会有不同的颜色。我们可以利用继承的方式来设计类的关系: 我们可以发现有很多的类,假如我们再增加一个形状或再增加一种颜色,就需要创建更多的类。 试…...

倾向得分匹配案例分析

一、倾向得分匹配法说明 倾向得分匹配模型是由Rosenbaum和Rubin在1983年提出的,首次运用在生物医药领域,后来被广泛运用在药物治疗、计量研究、政策实施评价等领域。倾向得分匹配模型主要用来解决非处理因素(干扰因素)的偏差。 …...

基于SpringCloud的可靠消息最终一致性04:项目基础代码

上一节给出了项目需求和骨架代码,这一节来接着看基础代码。骨架代码和基础代码最主要的区别是:骨架代码都是数据库脚本、POM依赖文件、配置文件内容、运维脚本等,而基础代码则是和业务有关联,但并非关键代码的部分。 这些代码不用一个个地看,主要是看看结构就行。 图二十五…...

操作系统权限提升(十八)之Linux提权-内核提权

Linux 内核提权 Linux 内核提权原理 内核提权是利用Linux内核的漏洞进行提权的,内核漏洞进行提权一般包括三个环节: 1、对目标系统进行信息收集,获取到系统内核信息及版本信息; 2、根据内核版本获取其对应的漏洞以及EXP 3、使…...

华为OD机试真题Java实现【快递运输】真题+解题思路+代码(20222023

快递运输 题目 一辆运送快递的货车,运送的快递均放在大小不等的长方体快递盒中,为了能够装载更多的快递,同时不能让货车超载,需要计算最多能装多少个快递。 注:快递的体积不受限制,快递数最多1000个,货车载重最大50000。 🔥🔥🔥🔥🔥👉👉👉👉👉�…...

java面试题-JVM问题排查

1.常见的Linux定位问题的工具?常见的 Linux 定位问题的命令可以分为以下几类:系统状态命令:包括 top、uptime、vmstat、sar 等命令,用于查看系统整体的状态,如 CPU 使用率、内存使用率、磁盘 I/O 等。进程状态命令&…...

市场上有很多低代码开发平台,不懂编程的人可以用哪些?

市场上有很多低代码开发平台,不懂编程的人可以用哪些?这个问题一看就是外行问的啦,低代码平台主打的就是一个“全民开发”,而且现在很多低代码平台都发展为零代码了,不懂编程也完全可以使用! 所谓低代码开…...

Tina_Linux打包流程说明指南_new

OpenRemoved_Tina_Linux_打包流程_说明指南_new 1 概述 1.1 编写目的 介绍Allwinner 平台上打包流程。 1.2 适用范围 Allwinner 软件平台Tina v3.0 版本以上。 1.3 相关人员 适用Tina 平台的广大客户,想了解Tina 打包流程的开发人员。 2 固件打包简介 固件…...

JVM面试题

JVM 1.jvm的组成部分 类加载器:将javac编译的class文件加载到内存中 运行时数据区:将内存划分成若干个不同的区域。 执行引擎:负责解析命令,提交操作系统执行。 本地接口:融合不同的语言为java所用 2.运行时数据区 方法区&…...

@FeignClient注解

1.在启动类上开启Feign功能 不开会提示找不到所需要的bean Consider defining a bean of type in your configuration SpringBootApplication EnableFeignClients public class AuthApplication {public static void main(String[] args) {SpringApplication.run(AuthApplic…...

一文搞懂如何在 React 中使用 防抖(Debounce)和 节流(Throttle)

在前端的日常开发中,经常会使用到两个函数防抖(Debounce)和节流(Throttle),防抖函数可以有效控制在一段时间内只执行最后一次请求,例如搜索框输入时,只在输入完成后才进行请求接口。…...

Airbyte API

Airbyte API涵盖了Airbyte功能的方方面面,主要分类:Source_definition:来源定义,实现了来源的增删改查功能。Destination_definition:目标定义,实现了目标的增删改查功能。Workspace:工作区管理…...

vue项目使用Electron开发桌面应用

添加npm配置避免安装Electron错误 请确保您的 node 版本大于等于 18. cmd运行: npm config edit 该命令会打开npm的配置文件,请在空白处添加: electron_builder_binaries_mirrorhttps://npmmirror.com/mirrors/electron-builder-binaries/ e…...

std::chrono笔记

文章目录1. radio原型作用示例2. duration原型:作用示例3. time_point原型作用示例4. clockssystem_clock示例steady_clock示例high_resolution_clock先说感觉,这个库真恶心,刚接触感觉跟shi一样,特别是那个命名空间,太…...

接收arp请求并发送回应的实例

本文简单介绍了arp协议,用一个实例查看收到的ARP请求,并对该请求发出ARP回应,实例有完整的源代码,使用C语言在Linux下实现,代码中有详细的注释。 1. ARP协议 ARP(Address Resolution Protocol),地址解析协议;在局域网上通过IP地址获取物理地址MAC的协议,该协议工作在数…...

【高性能计算】TVM使用TE手动优化矩阵乘法算法解析与代码解读

引言 注:本文主要介绍、解释TVM的矩阵优化思想、代码,需要配合代码注释一起阅读。 矩阵乘法是计算密集型运算。为了获得良好的 CPU 性能,有两个重要的优化措施: 提高内存访问的高速缓存命中率。复杂的数值计算和热点内存&#x…...

消息中间件的概念

中间件(middleware)是基础软件的一大类,属于可复用的软件范畴。中间件在操作系统软件,网络和数据库之上,应用软件之下,总的作用是为处于自己上层的应用软件提供运行于开发的环境,帮助用户灵活、高效的开发和集成复杂的…...

窃密恶意软件Raccoon最新样本Stealer v2分析

Raccoon 是一个恶意软件家族,2019 年来一直在地下犯罪论坛中以恶意软件即服务的身份进行售卖。2022 年 7 月,该恶意软件家族发布了 C 语言编写的新版本 Raccoon Stealer v2,打破了以往使用 C 开发的传统。 Raccoon 是一个信息窃密恶意软件&a…...

足球俱乐部管理系统

技术:Java、JSP等摘要:网站是一种主要的渠道。人们通过互联网快速、准确的发布信息、获取信息。而足球俱乐部是足球职业化、专业化的一个标志,是足球运动员以足球谋生时,所被聘用的机构,应运时代发展,规模、…...

2023上半年数学建模竞赛汇总(比赛时间、难易程度、含金量、竞赛官网)

1、美国大学生数学建模竞赛等级:国家级是否可跨校:否竞赛开始时间:2月17日~2月21日综合难度:⭐⭐⭐⭐ 竞赛含金量:⭐⭐⭐⭐⭐竞赛官网:https://www.comap.com/2、MathorCup高校数学建模挑战赛---大数据竞赛…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

Java 加密常用的各种算法及其选择

在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则&#xf…...

基于 TAPD 进行项目管理

起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

uniapp 字符包含的相关方法

在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

第八部分:阶段项目 6:构建 React 前端应用

现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...