Java设计模式 九 桥接模式 (Bridge Pattern)

桥接模式 (Bridge Pattern)

桥接模式是一种结构型设计模式,它的核心思想是将抽象部分与实现部分分离,使它们可以独立变化。这种模式通过组合而不是继承的方式来扩展功能,从而减少类之间的耦合度。


1. 模式结构

桥接模式的结构包括以下角色:

  • Abstraction(抽象类): 定义高层抽象部分,包含对实现部分(Implementor)的引用。
  • RefinedAbstraction(扩展抽象类): 继承抽象类,为高层部分提供更加具体的功能。
  • Implementor(实现接口): 定义实现类的接口,提供底层操作的抽象。
  • ConcreteImplementor(具体实现类): 实现具体的实现接口,定义底层操作的具体实现。

2. 桥接模式的优点

  1. 分离抽象与实现: 抽象部分和实现部分独立变化,降低耦合度。
  2. 扩展性强: 新增抽象部分或实现部分时无需修改已有代码,符合开闭原则。
  3. 提高灵活性: 可以动态地替换实现部分。

3. 桥接模式的缺点

  1. 增加复杂性: 分离抽象与实现后,会引入额外的类和接口。
  2. 过度设计: 如果系统不需要抽象与实现的独立扩展,使用桥接模式可能会导致不必要的设计复杂性。

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. 桥接模式的应用场景

  1. 多维度扩展:
    当一个类有两个或多个维度的变化时,比如“形状”和“颜色”、“设备”和“遥控器”等。

  2. 避免多层继承:
    使用桥接模式可以减少类的数量,避免因为每种功能扩展都使用继承而导致的类爆炸问题。

  3. 需要动态替换实现部分:
    在运行时需要动态更换实现类时,桥接模式可以提供灵活的组合方式。


6. 桥接模式的优缺点对比

优点:
  • 分离抽象和实现: 使两者可以独立变化,增强系统的灵活性。
  • 提高扩展性: 新增抽象或实现都很容易。
  • 运行时动态组合: 可以在运行时改变实现部分,满足动态需求。
缺点:
  • 增加复杂性: 系统需要维护抽象层和实现层的多个类和接口。
  • 可能造成过度设计: 如果变化维度较少,桥接模式可能显得不必要。

7. 桥接模式与其他模式的区别

模式主要用途与桥接模式的区别
适配器模式将一个接口转换为另一个接口适配器模式用于接口兼容问题,而桥接模式用于解耦抽象和实现。
装饰器模式动态地为对象添加新功能装饰器模式关注功能增强,桥接模式关注分离抽象和实现。
抽象工厂模式创建相关的对象家族抽象工厂模式注重产品家族的创建,桥接模式注重抽象和实现解耦。

8. 总结

桥接模式是一种灵活、优雅的结构型设计模式,它通过组合的方式将抽象与实现解耦,适合多维度变化的系统。它不仅提高了系统的扩展性,还减少了类的数量,避免多层继承导致的类爆炸问题。

在实际开发中,当系统需要应对复杂的变化时,桥接模式是一个非常有效的选择。

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

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

相关文章

Mybatis多条件查询:Map传参与对象传参解析

Mybatis 多条件查询常见且关键,本文探讨两种方法——Map 传参和 Java Bean 对象传参,展示用法及区别,总结应用场景和优缺点。 1. Map传参方式 原理:Mybatis允许我们通过一个Map对象来传递动态SQL中的参数。Map的键对应于SQL语句中…

wangEditor富文本编辑器,Laravel上传图片配置和使用

文章目录 前言步骤1. 构造好前端模版2. 搭建后端存储3. 调试 前言 由于最近写项目需要使用富文本编辑器,使用的是VUE3.0版本所以很多不兼容,实际测试以后推荐使用wangEditor 步骤 构造好前端模版搭建后端存储调试 1. 构造好前端模版 安装模版 模版安…

three.js+WebGL踩坑经验合集(2):3D场景被相机裁切后,被裁切的部分依然可以被鼠标碰撞检测得到(射线检测)

three.js内置了Raycaster类实现鼠标的碰撞检测,用它可以实现3D物体的鼠标点击,移入移出,触屏检测一类的业务功能。 该功能虽然强大,但同事们普遍反映不是那么好用,因为它不像其它配套了可视编辑的3D引擎一样&#xff…

Spring Boot spring.factories文件详细说明

优质博文:IT-BLOG-CN 前言:经常看到 spring.factories 文件,却没有对它进行深入的了解和分析,今天我们就一起揭开面纱看看它的内在。 spring.factories 文件是 Spring Boot 自动配置机制的核心部分之一。它位于每个 Spring Boo…

从前端视角看设计模式之行为型模式篇

上篇我们介绍了 设计模式之结构型模式篇,接下来介绍设计模式之行为型模式篇 责任链模式 责任链模式允许将请求沿着一条链传递,直到有一个对象处理它为止。每个处理者都有机会处理该请求,或者将其传递给链中的下一个处理者,每个处…

[2025分类时序异常检测指标R-AUC与VUS]

梳理了一下分类中常见的指标,这些指标与时序异常检测中新提出的A-RUC与VUS之间的关系 真正例(True Positive,TP): 被正确识别为正样本的数量。真负例(True Negative,TN): 被正确识别为负样本的数量。假正例(False Positive ,FP): 被错误识为正样本数量假负例(Fals…

Unity中实现伤害跳字效果(简单好抄)

第一步骤安装并导入Dotween插件(也可以不用导入之后直接下载我的安装包) 官网DOTween - 下载 第二步: 制作跳字预制体 建议把最佳适应打开,这样就不怕数字太大显示不全了。 第三步:创建一个空对象并编写脚本JumpNumbe…

考研机试:学分绩点

描述 北京大学对本科生的成绩施行平均学分绩点制(GPA)。 既将学生的实际考分根据不同的学科的不同学分按一定的公式进行计算。 公式如下: 一门课程的学分绩点 该课绩点 该课学分 总评绩点 所有学科学分绩点之和 / 所有课程学分之和 …

【玩转全栈】----YOLO8训练自己的模型并应用

继上篇: 【玩转全栈】---基于YOLO8的图片、视频目标检测-CSDN博客 相信大家已经可以训练一些图片和视频了,接下来我将为大家介绍如何训练自己的特定模型,并用其进行检测 目录 准备数据 图片数据 标识数据 配置文件 运行 测试训练结果 存在的问…

OpenCV文字绘制支持中文显示

OpenCV版本:4.4 IDE:VS2019 功能描述 OpenCV绘制文本的函数putText()不支持中文的显示,网上很多方法推荐的都是使用FreeType来支持,FreeType是什么呢?FreeType的官网上有介绍 FreeType官网 https://www.freetype.or…

我谈《概率论与数理统计》的知识体系

学习《概率论与数理统计》二十多年后,在廖老师的指导下,才厘清了各章之间的关系。首先,这是两个学科综合的一门课程,这一门课程中还有术语冲突的问题。这一门课程一条线两个分支,脉络很清晰。 概率论与统计学 概率论…

ElasticSearch JavaRestClient查询之快速入门

文章目录 查询操作流程概述构建并发起请求1. 创建请求对象2. 设置请求体3. 发送请求 查询结果的解析1. 解析结果结构2. 获取总条数3. 获取命中的数据 完整示例代码总结 查询操作流程概述 Elasticsearch 查询操作大致可以分为两个部分: 构建并发起请求:…

Quartus:开发使用及 Tips 总结

Quartus是Altera(现已被Intel收购)推出的一款针对其FPGA产品的综合性开发环境,用于设计、仿真和调试数字电路。以下是使用Quartus的一些总结和技巧(Tips),帮助更高效地进行FPGA项目开发: 这里写目录标题 使用总结TIPS…

elementUI Table组件实现表头吸顶效果

需求描述 当 table 内容过多的时候,页面上滑滚动,表头的信息也会随着被遮挡,无法将表头信息和表格内容对应起来,需要进行表头吸顶 开始编码💪 环境:vue2.6、element UI step1: 给el-table__h…

用于牙科的多任务视频增强

Multi-task Video Enhancement for Dental Interventions 2022 miccai Abstract 微型照相机牢牢地固定在牙科手机上,这样牙医就可以持续地监测保守牙科手术的进展情况。但视频辅助牙科干预中的视频增强减轻了低光、噪音、模糊和相机握手等降低视觉舒适度的问题。…

Vue3轮播图左右联动

1、轮播图部分,右边鼠标移入,左边对应展示轮播图 可以在swiper 官网 Swiper中文网-轮播图幻灯片js插件,H5页面前端开发 选择vue中使用swiper npm i swiper 左右两边的联动:左边的轮播图和右边的小的列表他们的列表组成结构是一样的&#…

windows下本地部署安装hadoop+scala+spark-【不需要虚拟机】

注意版本依赖【本实验版本如下】 Hadoop 3.1.1 spark 2.3.2 scala 2.11 1.依赖环境 1.1 java 安装java并配置环境变量【如果未安装搜索其他教程】 环境验证如下: C:\Users\wangning>java -version java version "1.8.0_261" Java(TM) SE Runti…

go-zero框架基本配置和错误码封装

文章目录 加载配置信息配置 env加载.env文件配置servicecontext 查询数据生成model文件执行查询操作 错误码封装配置拦截器错误码封装 接上一篇:《go-zero框架快速入门》 加载配置信息 配置 env 在项目根目录下新增 .env 文件,可以配置当前读取哪个环…

2025 最新flutter面试总结

目录 1.Dart是值传递还是引用传递? 2.Flutter 是单引擎还是双引擎 3. StatelessWidget 和 StatefulWidget 在 Flutter 中有什么区别? 4.简述Dart语音特性 5. Navigator 是什么?在 Flutter 中 Routes 是什么? 6、Dart 是不是…

HarmonyOS Next构建工具 lycium 原理介绍

HarmonyOS Next构建工具 lycium 原理介绍 背景介绍 HarmonyOS Next中很多系统API是以C接口提供,如果要使用C接口,必须要使用NAPI在ArkTS与C间交互,这种场景在使用DevEco-Studio中集成的交叉编译工具,以及cmake构建工具就完全够用…