Java设计模式 九 桥接模式 (Bridge Pattern)
桥接模式 (Bridge Pattern)
桥接模式是一种结构型设计模式,它的核心思想是将抽象部分与实现部分分离,使它们可以独立变化。这种模式通过组合而不是继承的方式来扩展功能,从而减少类之间的耦合度。
1. 模式结构
桥接模式的结构包括以下角色:
- Abstraction(抽象类): 定义高层抽象部分,包含对实现部分(Implementor)的引用。
- RefinedAbstraction(扩展抽象类): 继承抽象类,为高层部分提供更加具体的功能。
- Implementor(实现接口): 定义实现类的接口,提供底层操作的抽象。
- ConcreteImplementor(具体实现类): 实现具体的实现接口,定义底层操作的具体实现。
2. 桥接模式的优点
- 分离抽象与实现: 抽象部分和实现部分独立变化,降低耦合度。
- 扩展性强: 新增抽象部分或实现部分时无需修改已有代码,符合开闭原则。
- 提高灵活性: 可以动态地替换实现部分。
3. 桥接模式的缺点
- 增加复杂性: 分离抽象与实现后,会引入额外的类和接口。
- 过度设计: 如果系统不需要抽象与实现的独立扩展,使用桥接模式可能会导致不必要的设计复杂性。
4. 桥接模式的实现
示例场景:设备与遥控器
我们以“设备(电视、收音机)”和“遥控器(基础遥控器、高级遥控器)”为例,实现桥接模式。
1) 定义实现接口
定义设备的通用操作接口。
// 实现接口
public interface Device {void turnOn();void turnOff();void setVolume(int percent);int getVolume();
}
2) 实现具体设备类
具体设备类实现 Device
接口。
// 电视实现类
public class TV implements Device {private int volume = 50;@Overridepublic void turnOn() {System.out.println("TV is turned on.");}@Overridepublic void turnOff() {System.out.println("TV is turned off.");}@Overridepublic void setVolume(int percent) {this.volume = percent;System.out.println("TV volume set to " + percent + "%.");}@Overridepublic int getVolume() {return volume;}
}// 收音机实现类
public class Radio implements Device {private int volume = 30;@Overridepublic void turnOn() {System.out.println("Radio is turned on.");}@Overridepublic void turnOff() {System.out.println("Radio is turned off.");}@Overridepublic void setVolume(int percent) {this.volume = percent;System.out.println("Radio volume set to " + percent + "%.");}@Overridepublic int getVolume() {return volume;}
}
3) 定义抽象类
定义遥控器的抽象类,并持有设备接口的引用。
// 抽象遥控器
public abstract class RemoteControl {protected Device device;public RemoteControl(Device device) {this.device = device;}public void turnOn() {device.turnOn();}public void turnOff() {device.turnOff();}public void setVolume(int percent) {device.setVolume(percent);}
}
4) 实现具体遥控器
扩展遥控器的功能。
// 基础遥控器
public class BasicRemote extends RemoteControl {public BasicRemote(Device device) {super(device);}public void mute() {System.out.println("Muting the device.");device.setVolume(0);}
}
5) 客户端代码
通过桥接模式实现动态组合。
public class Client {public static void main(String[] args) {// 使用 TV 和基础遥控器Device tv = new TV();RemoteControl tvRemote = new BasicRemote(tv);tvRemote.turnOn();tvRemote.setVolume(70);((BasicRemote) tvRemote).mute();tvRemote.turnOff();// 使用 Radio 和基础遥控器Device radio = new Radio();RemoteControl radioRemote = new BasicRemote(radio);radioRemote.turnOn();radioRemote.setVolume(50);((BasicRemote) radioRemote).mute();radioRemote.turnOff();}
}
运行结果:
TV is turned on.
TV volume set to 70%.
Muting the device.
TV volume set to 0%.
TV is turned off.
Radio is turned on.
Radio volume set to 50%.
Muting the device.
Radio volume set to 0%.
Radio is turned off.
5. 桥接模式的应用场景
-
多维度扩展:
当一个类有两个或多个维度的变化时,比如“形状”和“颜色”、“设备”和“遥控器”等。 -
避免多层继承:
使用桥接模式可以减少类的数量,避免因为每种功能扩展都使用继承而导致的类爆炸问题。 -
需要动态替换实现部分:
在运行时需要动态更换实现类时,桥接模式可以提供灵活的组合方式。
6. 桥接模式的优缺点对比
优点:
- 分离抽象和实现: 使两者可以独立变化,增强系统的灵活性。
- 提高扩展性: 新增抽象或实现都很容易。
- 运行时动态组合: 可以在运行时改变实现部分,满足动态需求。
缺点:
- 增加复杂性: 系统需要维护抽象层和实现层的多个类和接口。
- 可能造成过度设计: 如果变化维度较少,桥接模式可能显得不必要。
7. 桥接模式与其他模式的区别
模式 | 主要用途 | 与桥接模式的区别 |
---|---|---|
适配器模式 | 将一个接口转换为另一个接口 | 适配器模式用于接口兼容问题,而桥接模式用于解耦抽象和实现。 |
装饰器模式 | 动态地为对象添加新功能 | 装饰器模式关注功能增强,桥接模式关注分离抽象和实现。 |
抽象工厂模式 | 创建相关的对象家族 | 抽象工厂模式注重产品家族的创建,桥接模式注重抽象和实现解耦。 |
8. 总结
桥接模式是一种灵活、优雅的结构型设计模式,它通过组合的方式将抽象与实现解耦,适合多维度变化的系统。它不仅提高了系统的扩展性,还减少了类的数量,避免多层继承导致的类爆炸问题。
在实际开发中,当系统需要应对复杂的变化时,桥接模式是一个非常有效的选择。
相关文章:
Java设计模式 九 桥接模式 (Bridge Pattern)
桥接模式 (Bridge Pattern) 桥接模式是一种结构型设计模式,它的核心思想是将抽象部分与实现部分分离,使它们可以独立变化。这种模式通过组合而不是继承的方式来扩展功能,从而减少类之间的耦合度。 1. 模式结构 桥接模式的结构包括以下角色&…...
stm8s单片机(二)外部中断实验
中断优先级 stm8的中断优先级不是固定不变的,stm8的中断分为硬件优先级与软件优先级;当多个中断发生时,cpu会先响应软件优先级高的中断,若软件优先级相同会先响应硬件优先级高的; 其中软件优先级有四个 /*** brief …...
计算机网络 (53)互联网使用的安全协议
一、SSL/TLS协议 概述: SSL(Secure Sockets Layer)安全套接层和TLS(Transport Layer Security)传输层安全协议是工作在OSI模型应用层的安全协议。SSL由Netscape于1994年开发,广泛应用于基于万维网的各种网络…...
数学基础 --线性代数之理解矩阵乘法
理解矩阵乘法的解析 矩阵乘法(Matrix Multiplication)是线性代数中的核心操作之一。在数学、几何和工程实际中,它不仅是一种代数运算规则,还承载着丰富的几何和映射意义。本文将从多个角度深入解析矩阵乘法,帮助读者理…...
数学规划问题2 .有代码(非线性规划模型,最大最小化模型,多目标规划模型)
非线性规划模型 FIrst:转化为标准型 在matlab中求非线性规划的函数 练习题: 典型例题: 最大最小化模型 核心思想: matlab的模型求解 经典例题: 多目标规划模型 基本概念 求解思路: 模型构建步骤 经典例题: 非线性规划模型 非线性规划(Nonl…...
jax 和 jaxlib 的 cuda 版本安装
笔者花费时间才在 Ubuntu 20.04 适配上 jax 和 jaxlib 的 cuda 版本安装,以及 chex 版本。 版本展示 本人版本展示 jax0.4.27 ,jaxlib0.4.27cuda12.cudnn89,chex0.1.86。 安装过程 cuda 以及环境变量配置过程 首先安装cuda12.4和cudnn8.9&…...
Spring Boot MyBatis Plus 版本兼容问题(记录)
Spring Boot & MyBatis Plus 版本兼容问题(Invalid value type for attribute factoryBeanObjectType: java.lang.String) 问题描述问题排查1. 检查 MapperScan 的路径2. 项目中没有配置 FactoryBean3. 检查 Spring 和 MyBatis Plus 版本兼容性 解决…...
Ubuntu如何安装redis服务?
环境: Ubuntu22.04 WSL2 问题描述: 如何安装redis服务? 解决方案: 1.在 Linux 上(如 Ubuntu/Debian)安装 1.通过包管理工具安装 Redis 服务器: sudo apt update sudo apt install redis…...
FFmpeg 头文件完美翻译之 libavcodec 模块
前言 众所周知,FFmpeg 的代码开发上手难度较高,源于官方提供的文档很少有包含代码教程相关的。要想熟练掌握 FFmpeg 的代码库开发,需要借助它的头文件,FFmpeg 把很多代码库教程都写在头文件里面。因此,熟读头文件的内…...
设计模式的艺术-单一职责原则
1.基础知识 是最简单的面向对象设计原则,它用于控制类的粒度大小。 一个类只负责一个功能领域中的相应职责。 单一职责原则的核心思想是:一个类不能太“累”!在软件系统中,一个类(大到模块,小到方法&…...
MySQL主从配置
一、 主从原理 MySQL 主从同步是一种数据库复制技术,它通过将主服务器上的数据更改复制到一个或多个从服务器,实现数据的自动同步。主从同步的核心原理是将主服务器上的二进制日志复制到从服务器,并在从服务器上执行这些日志中的操作。 二、主…...
【Unity3D实现雨下在窗户上的效果】
系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、效果展示👉二、原理👉三、使用步骤3-1、shader代码纹理映射数学运算和函数的运用特效算法的实现高效的性能优化👉壁纸分享👉总结👉前言 想要好看的效果肯定是要用shader实现啦,为什么呢? 因为Shade…...
k8s资源预留
k8s资源预留 https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/reserve-compute-resources/ vim /var/lib/kubelet/config.yamlenforceNodeAllocatable: - pods kubeReserved: # 配置 kube 资源预留cpu: 500mmemory: 1Giephemeral-storage: 1Gi systemReserved: #…...
云计算与物联网技术的融合应用(在工业、农业、家居、医疗、环境、城市等整理较全)
摘要 为生产领域带来更加全面和深入的变革。通过云计算平台对物联网数据进行处理和分析,企业可以实现对生产过程的更加精细化的管理和控制。 1. 智能生产调度 通过云计算和物联网技术的融合应用,企业可以实现对生产线上各个环节的实时监控和数据分析。…...
【深度学习】2.视觉问题与得分函数
计算机视觉任务 可以通过神经网络搜索是什么类别的动物。 图像实际就是含有数值的三维矩阵。 像素值从0-255可以表示亮度递增的参数。数字越大,像素点越亮。 最后的3表示三个颜色通道,常见的如JPG、RGB等。 现实场景容易发生各种遮蔽现象。 计算机判断…...
Node.js——express中间件(全局中间件、路由中间件、静态资源中间件)
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
安卓动态设置Unity图形API
命令行方式 Unity图像api设置为自动,安卓动态设置Vulkan、OpenGLES Unity设置 安卓设置 创建自定义活动并将其设置为应用程序入口点。 在自定义活动中,覆盖字符串UnityPlayerActivity。updateunitycommandlineararguments (String cmdLine)方法。 在该方法中,将cmdLine…...
VMware虚拟机迁移到阿里云
VMware虚拟机迁移到阿里云是一个涉及多个步骤的过程,具体如下: 使用阿里云的服务器迁移中心(SMC)进行P2V或V2V迁移。如果是小型应用,可以通过制作镜像文件然后上传至阿里云OSS,并基于该镜像创建ECS实例。对…...
2025年1月22日(什么是扫频)
扫频(Sweep Frequency)是一种信号处理技术,通常用于系统识别、频率响应分析和特性测试。它通过发送一个频率逐渐变化的信号(通常是正弦波或线性调频信号)来激励系统,然后测量系统的响应。这种方法可以帮助我…...
前端开发中的模拟后端与MVVM架构实践[特殊字符][特殊字符][特殊字符]
平时,后端可能不能及时给接口给前端进行数据调用和读取。这时候,前端想到进行模拟后端接口。本文将介绍如何通过vite-plugin-mock插件模拟后端接口,并探讨MVVM架构在前端开发中的应用。此外,我们还将讨论Vue2与Vue3的区别…...
Win10系统部署RabbitMQ Server
文章目录 版本说明依赖安装添加Erlang环境变量验证Erlang安装 RabbitMQ Server安装解压启动查看RabbitMQ插件安装rabbitmq_management插件再次启动设置RabbitMQ为系统服务 版本说明 ErlangRabbitMQ27.24.0.5 可以在Erlang官网和RabbitMQ官网下载安装包,安装已下载…...
Java web与Java中的Servlet
一。前言 Java语言大多用于开发web系统的后端,也就是我们是的B/S架构。通过浏览器一个URL去访问系统的后端资源和逻辑。 当我在代码里看到这个类HttpServletRequest 时 让我想到了Servlet,Servlet看上去多么像是Java的一个普通类,但是它确实…...
Web开发 -前端部分-CSS3新特性
1 CSS概述 2 CSS3私有前缀 3 CSS3的长度单位 代码实现: <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…...
2025年PHP面试宝典,技术总结。
面试是进入职场的第一道坎,因为我本身学校太一般的问题在面试中遇到了各种不爽,和那些高学历的相比自己真是信心大跌。我面试的方向是php开发工程师,主要做网站后台、APP接口等。下面是我这段时间总结的面试方面的常考常问的知识点࿰…...
idea plugin插件开发——入门级教程(IntelliJ IDEA Plugin)
手打不易,如果转摘,请注明出处! 注明原文:idea plugin插件开发——入门级教程(IntelliJ IDEA Plugin)-CSDN博客 目录 前言 官方 官方文档 代码示例 开发前必读 Intellij、Gradle、JDK 版本关系 plu…...
node.js 文件操作
在 Node.js 中,文件操作主要通过内置的 fs(File System)模块来实现。 1. 读取文件 const fs require("fs");// 异步读取文件fs.readFile("example.txt", "utf8", (err, data) > {if (err) {console.erro…...
模拟算法习题篇
在算法中,模拟是一种通过计算机程序来模拟现实世界中的过程或系统行为的方法。它的核心思想是根据题目给定的规则和逻辑,按照步骤细致地重现事件的发展流程,从而获得最终结果。 解题时如何使用模拟算法: 理解题目规则:…...
opencv对直方图的计算和绘制
【欢迎关注编码小哥,学习更多实用的编程方法和技巧】 1、直方图的计算 cv::calcHist 是 OpenCV 中用于计算图像直方图的函数。它可以处理多通道图像,并通过指定图像、通道、掩膜、直方图大小和范围等参数来生成直方图。 函数原型 void cv::calcHist(…...
暑期实习准备:C语言(持续更新)
1.局部变量和全局变量 局部变量的作用域是在变量所在的局部范围,全局变量的作用域是整个工程;局部变量的生命周期是作用域内,全局变量的生命周期是整个程序的生命周期,当两者命名冲突时,优先使用的是局部变量。 2.C语言…...
一文大白话讲清楚webpack基本使用——11——chunkIds和runtimeChunk
文章目录 一文大白话讲清楚webpack基本使用——11——chunkIds和runtimeChunk1. 建议按文章顺序从头看,一看到底,豁然开朗2. 啥是chunkIds3.怎么使用chunkIds4. 啥是runtimeChunk5. 怎么使用runtimeChunk 一文大白话讲清楚webpack基本使用——11——chun…...
linux下使用脚本实现对进程的内存占用自动化监测
linux系统中常用cat /proc/{pid}/status和pmap -x {pid}来监测某个进程的内存资源占用情况。 其中注意各参数的含义如下: VmSize:表示进程当前虚拟内存大小 VmPeak:表示进程所占用最大虚拟内存大小 VmRSS:表示进程当前占用物理内…...
MyBatis Plus 的 InnerInterceptor:更轻量级的 SQL 拦截器
在 Spring Boot 项目中使用 MyBatis Plus 时,你可能会遇到 InnerInterceptor 这个概念。 InnerInterceptor 是 MyBatis Plus 提供的一种轻量级 SQL 拦截器,它与传统的 MyBatis 拦截器(Interceptor)有所不同,具有更简单…...
[STM32 HAL库]串口中断编程思路
一、前言 最近在准备蓝桥杯比赛(嵌入式赛道),研究了以下串口空闲中断DMA接收不定长的数据,感觉这个方法的接收效率很高,十分好用。方法配置都成功了,但是有一个点需要进行考虑,就是一般我们需要…...
会议签到系统的架构和实现
会议签到系统的架构和实现 摘要:通过定制安卓会议机开机APP呈现签到界面,并且通过W/B结构采集管理签到信息,实现会议签到的功能。为达到此目标本文将探讨使用Redis提供后台数据支持;使用SocketIo处理适时消息;使用Flask进行原型开…...
复位信号的同步与释放(同步复位、异步复位、异步复位同步释放)
文章目录 背景前言一、复位信号的同步与释放1.1 同步复位1.1.1 综述1.1.2 优缺点 1.2 recovery time和removal time1.3 异步复位1.3.1 综述1.3.2 优缺点 1.4 同步复位 与 异步复位1.5 异步复位、同步释放1.5.1 总述1.5.2 机理1.5.3 复位网络 二、思考与补充2.1 复…...
TL3562/3568移植无锡沐创N500L-AM4驱动进内核源码,报错及其解决方案
前言 创龙官方提供的资料无锡沐创N500L-AM4驱动是rnpgbe-0.1.0.rc60-dd9f3cf.tar.gz;无锡沐创官方,截止目前,最新驱动是rnpgbe-0.2.3-f26b9a4.tar.gz。考虑到开发的稳妥性,先选用创龙尝试过的rnpgbe-0.1.0.rc60-dd9f3cf.tar.gz来移…...
埃氏算法C++实现: 快速输出质数( 素数 )
目录 1.简介 算法原理 算法特点 应用场景 2.一般求素数方法 3.埃氏算法求素数 3.1.无动态分配 3.2.有动态分配 1.简介 埃氏算法(Eratosthenes Sieve),全称为埃拉托斯特尼筛法,是一种由古希腊数学家埃拉托斯特尼在公元…...
Kubernetes 集群中安装和配置 Kubernetes Dashboard
前言 上篇成功部署Kubernetes集群后,为了方便管理和监控集群资源,安装Kubernetes Dashboard显得尤为重要。Kubernetes Dashboard 是一个通用的、基于 Web 的 UI,旨在让用户轻松地部署容器化应用到 Kubernetes 集群,并对这些应用进…...
力扣-数组-414 第三大的数
解析 先利用set去重,然后用逆向遍历找到第三大的数 代码 class Solution { public:int thirdMax(vector<int>& nums) {set<int> numsToset;for(int i 0; i<nums.size(); i){numsToset.insert(nums[i]);}int index;if(numsToset.size() > …...
python实现答题游戏
有这样一个需求:使用python实现一个游戏,一共有10个问题,依次回答每个问题,每个用户可以输入问题的答案,但是互相不能看到,有一个管理员可以看到所有人的答案,并且当所有人都填写完成后可以公布…...
OneData体系架构详解
阿里巴巴的 OneData 体系架构方法论,主要分为三个阶段:业务板块、规范定义 和 模型设计。每个阶段的核心目标是确保数据的高效管理、共享与分析能力。 一. 业务板块(Business Segment) 业务板块是OneData体系架构中的第一步&…...
五、华为 RSTP
RSTP(Rapid Spanning Tree Protocol,快速生成树协议)是 STP 的优化版本,能实现网络拓扑的快速收敛。 一、RSTP 原理 快速收敛机制:RSTP 通过引入边缘端口、P/A(Proposal/Agreement)机制等&…...
解锁Java中的国密算法:安全保障的密钥
一、引言 在数字化浪潮席卷全球的当下,信息安全已然成为国家、企业乃至个人无法忽视的重要议题。国密算法,作为我国自主研发的密码算法体系,宛如坚固的盾牌,为国家信息安全筑起了一道坚不可摧的防线。它的诞生,不仅承载…...
docker-registry
安装依赖 apt install apache2-utils设置密码 htpasswd -Bbn 用户名 密码 >/data/registry_hub/passwd#docker私服部署 docker run -d -p 5000:5000 --name docker-registry -v /data/registry_hub/:/var/lib/registry -v /data/registry_hub/passwd:/auth/htpasswd \ -e …...
QTableWidget的简单使用
1.最简单的表格示例: ui->tableWidget->setRowCount(2);// 设置行数ui->tableWidget->setColumnCount(3);// 设置列数,一定要放在设置行表头之前QStringList rowHeaderList;// 行表头rowHeaderList << QStringLiteral("姓名"…...
第三天 学习JavaScript基础,掌握变量、数据类型、运算符、流程控制
学习JavaScript基础是成为一名前端开发者的重要一步。以下是关于变量、数据类型、运算符和流程控制的一些基础知识和示例代码。 1. 变量 变量用于存储数据。在JavaScript中,使用var、let或const关键字来声明变量。 // 使用 var 声明变量(不推荐&#…...
Python - itertools- pairwise函数的详解
前言: 最近在leetcode刷题时用到了重叠对pairwise,这里就讲解一下迭代工具函数pairwise,既介绍给大家,同时也提醒一下自己,这个pairwise其实在刷题中十分有用,相信能帮助到你。 参考官方讲解:itertools --- 为高效循…...
C语言程序设计十大排序—选择排序
文章目录 1.概念✅2.选择排序🎈3.代码实现✅3.1 直接写✨3.2 函数✨ 4.总结✅5.十大排序 1.概念✅ 排序是数据处理的基本操作之一,每次算法竞赛都很多题目用到排序。排序算法是计算机科学中基础且常用的算法,排序后的数据更易于处理和查找。在…...
微前端qiankun的基本使用(vue-element-admin作为项目模版)
微前端qiankun的基本使用(vue-element-admin作为项目模版) qiankun架构特点主应用netmoni_master改造工程项目目录结构子项目配置:子应用注册配置项container:子应用挂载节点配置项activeRule:子应用路由子应用netmoni_child1改造目录结构项目配置:src/settings中配置子应…...
MySQL用户授权、收回权限与查看权限
【图书推荐】《MySQL 9从入门到性能优化(视频教学版)》-CSDN博客 《MySQL 9从入门到性能优化(视频教学版)(数据库技术丛书)》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…...