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

软件设计模式系列之九——桥接模式

1 模式的定义

桥接模式是一种结构型设计模式,它用于将抽象部分与其实现部分分离,以便它们可以独立地变化。这种模式涉及一个接口,它充当一个桥,使得具体类可以在不影响客户端代码的情况下改变。桥接模式将继承关系转化为组合关系,从而减少类之间的紧密耦合度,使得系统更加灵活和可扩展。

桥接模式的核心思想是将系统中的多个维度的变化解耦,使得每个维度可以独立地扩展和修改,而不会影响到其他维度。这使得系统更加灵活,易于维护和扩展。桥接模式通常应用于需要处理多个变化维度的场景,如不同操作系统和应用程序之间的通信、多种格式和不同设备的兼容性等。

2 举例说明

让我们通过一个简单的例子来说明桥接模式。
在这里插入图片描述

比如在视频播放器的场景中,我们可以使用桥接模式来处理两个独立变化的维度:视频格式和操作系统。视频格式维度包括FLV、AVI、MP4等不同的视频格式,操作系统维度包括Windows、Linux、macOS、Android等不同的操作系统。通过桥接模式,我们可以创建具有不同视频格式和运行在不同操作系统上的播放器,同时保持代码的可扩展性和可维护性。这意味着我们可以轻松地添加新的视频格式和支持新的操作系统,而不会对现有代码造成影响。

3 结构

桥接模式的结构包括以下几个关键组件:
在这里插入图片描述

抽象类(Abstraction):定义抽象部分的接口,维护一个指向实现部分的引用。
扩展抽象类(Refined Abstraction):扩展抽象类,实现更多特定功能。
实现接口(Implementor):定义实现部分的接口,通常包括具体操作的方法。
具体实现类(Concrete Implementor):实现接口的具体实现。

4 实现步骤

桥接模式的实现步骤如下:

定义实现接口(Implementor),并在其中声明抽象方法。
创建具体实现类(Concrete Implementor),实现实现接口中的方法。
定义抽象类(Abstraction),包含一个指向实现接口的引用,并在其中定义抽象方法。
创建扩展抽象类(Refined Abstraction),继承抽象类,并实现具体功能,可以调用实现接口中的方法。
在客户端代码中使用抽象类和具体实现类。

5 代码实现

// 实现接口 - 视频播放器实现
interface VideoPlayerImplementor {void playVideo();
}// 具体实现类 - 不同视频格式的播放器
class FLVVideoPlayer implements VideoPlayerImplementor {public void playVideo() {System.out.println("播放FLV格式的视频。");}
}class AVIVideoPlayer implements VideoPlayerImplementor {public void playVideo() {System.out.println("播放AVI格式的视频。");}
}class MP4VideoPlayer implements VideoPlayerImplementor {public void playVideo() {System.out.println("播放MP4格式的视频。");}
}// 抽象类 - 视频播放器
abstract class VideoPlayer {protected VideoPlayerImplementor implementor;public VideoPlayer(VideoPlayerImplementor implementor) {this.implementor = implementor;}public abstract void play();
}// 扩展抽象类 - 不同操作系统上的视频播放器
class WindowsVideoPlayer extends VideoPlayer {public WindowsVideoPlayer(VideoPlayerImplementor implementor) {super(implementor);}public void play() {System.out.println("在Windows系统上播放视频:");implementor.playVideo();}
}class LinuxVideoPlayer extends VideoPlayer {public LinuxVideoPlayer(VideoPlayerImplementor implementor) {super(implementor);}public void play() {System.out.println("在Linux系统上播放视频:");implementor.playVideo();}
}class MacOSVideoPlayer extends VideoPlayer {public MacOSVideoPlayer(VideoPlayerImplementor implementor) {super(implementor);}public void play() {System.out.println("在macOS系统上播放视频:");implementor.playVideo();}
}class AndroidVideoPlayer extends VideoPlayer {public AndroidVideoPlayer(VideoPlayerImplementor implementor) {super(implementor);}public void play() {System.out.println("在Android系统上播放视频:");implementor.playVideo();}
}public class Client {public static void main(String[] args) {VideoPlayerImplementor flvPlayer = new FLVVideoPlayer();VideoPlayerImplementor mp4Player = new MP4VideoPlayer();VideoPlayer windowsFLVPlayer = new WindowsVideoPlayer(flvPlayer);VideoPlayer linuxMP4Player = new LinuxVideoPlayer(mp4Player);windowsFLVPlayer.play();  // 在Windows系统上播放FLV视频linuxMP4Player.play();    // 在Linux系统上播放MP4视频}
}

在这个示例中,我们首先定义了视频播放器的实现接口(VideoPlayerImplementor),然后创建了具体实现类,表示不同视频格式的播放器。接着,我们定义了视频播放器的抽象类(VideoPlayer)和扩展抽象类,表示不同操作系统上的播放器。最后,通过客户端代码,我们可以选择不同的视频格式和操作系统,实现了桥接模式的应用。这使我们能够轻松扩展支持更多格式和操作系统的播放器,而不会修改现有代码。

6 典型应用场景

桥接模式在以下情况下非常有用:

当你需要避免在抽象和具体实现之间存在静态绑定关系时。
当一个类存在多个独立变化的维度,且需要独立扩展时,可以使用桥接模式来管理这些维度。
当你希望一个抽象部分的变化不会影响到客户端代码时,可以使用桥接模式。
典型应用包括不同操作系统上的图形用户界面库、不同数据库连接的数据库访问库等。

7 优缺点

优点:
解耦性:桥接模式将抽象和实现分离,降低了它们之间的耦合度。
可扩展性:可以方便地添加新的抽象和具体实现,而不会影响到已有的代码。
可维护性:由于分离了抽象和具体实现,代码更容易理解和维护。
符合开闭原则:可以在不修改现有代码的情况下扩展系统功能。
缺点:
增加复杂性:引入了额外的抽象层次,可能会增加代码的复杂性。
增加开发时间:相对于直接使用继承,桥接模式可能需要更多的开发时间

8 类似模式

桥接模式和类似模式中,有两种最常见的模式是适配器模式和装饰者模式。它们都属于结构型设计模式,并且在某些情况下可以与桥接模式有一定的联系。
在这里插入图片描述

  • 适配器模式(Adapter Pattern)

联系:适配器模式通常用于使一个类的接口与另一个类的接口兼容,它的主要目的是使接口不兼容的类能够协同工作。在某种程度上,适配器模式也可以解决桥接模式中的问题,因为它们都涉及将不同的接口协同工作。

区别:适配器模式的主要焦点是在不同接口之间进行适配,通常是通过包装一个类来实现。而桥接模式的主要焦点是将抽象部分与实现部分分离,允许它们独立变化。桥接模式更加注重组合而不是适配。

  • 装饰者模式(Decorator Pattern)

联系:装饰者模式和桥接模式都涉及到在运行时组合对象,而不是静态继承。它们都允许你在不修改核心类的情况下增加功能。

区别:装饰者模式主要用于动态地添加额外的职责或行为,而不改变对象的接口。它通常以一种递归的方式构建,每个装饰者都有一个基本组件的引用。相反,桥接模式的主要目标是将抽象部分和实现部分分离,以便它们可以独立变化,而不影响客户端。

虽然这些模式有一些相似之处,但它们的关注点和目标略有不同。桥接模式主要关注将抽象和实现分离,允许它们独立变化,通常涉及多个维度的变化。适配器模式主要关注接口的适配,以使不兼容的类能够协同工作。装饰者模式主要用于动态地增加对象的功能。在实际应用中,选择合适的模式取决于具体问题的需求。

9 小结

桥接模式是一种强大的设计模式,它可以将抽象和实现分离,使得系统更加灵活、可扩展和易于维护。通过示例、结构、实现步骤、代码实现、典型应用场景、优缺点以及类似模式的介绍,我们希望您现在对桥接模式有了更深入的理解,并能够在实际项目中合理应用它以解决复杂性和提高代码质量。桥接模式适用于需要处理多个独立变化维度的情况,以及需要保持灵活性和可扩展性的项目中。

在使用桥接模式时,确保仔细设计抽象和实现部分的接口,以便将它们正确连接起来。同时,要注意避免过度使用桥接模式,因为它可能增加代码的复杂性,只有在确实需要将抽象和实现分离时才应该采用这种模式。

最后,深入理解设计模式并将其应用到实际项目中需要时间和实践。桥接模式是设计模式中的一个重要工具,它可以帮助你构建更加灵活和可维护的软件系统。希望这篇博客能够帮助你更好地理解和应用桥接模式。

相关文章:

软件设计模式系列之九——桥接模式

1 模式的定义 桥接模式是一种结构型设计模式,它用于将抽象部分与其实现部分分离,以便它们可以独立地变化。这种模式涉及一个接口,它充当一个桥,使得具体类可以在不影响客户端代码的情况下改变。桥接模式将继承关系转化为组合关系…...

构造函数的调用规则

#include <iostream> #include <string> using namespace std; class person{ public:int m_age; // person(){ // cout<<"默认构造的调用"<<endl; // } // person(int age){ // m_ageage; // cout<<"有参构造的调用"<…...

第十章:枚举类与注解

10.1&#xff1a;枚举类的使用 当需要定义一组常量时&#xff0c;建议使用枚举类&#xff08;前提&#xff1a;类的对象只有有限个&#xff0c;确定的&#xff09; eg&#xff1a; 星期&#xff1a;Mondey、.....、Sunday 性别&#xff1a;Man、.....、Woman 线程状态&#xff…...

ChatGPT:字符串操作问题——提取包含括号的字符串中的题干内容

ChatGPT&#xff1a;字符串操作问题——提取包含括号的字符串中的题干内容 String title p.text().split(“(”)[0];为什么会报错 ChatGPT&#xff1a; 在这段代码中&#xff0c;您正在使用Java处理一个字符串&#xff08;假设是HTML或文本&#xff09;&#xff0c;尝试将其分…...

jvm中对象创建、内存布局以及访问定位

对象创建 Java语言层面&#xff0c;创建对象通常&#xff08;例外&#xff1a;复制、反序列化&#xff09;仅仅是一个new关键字即可&#xff0c;而在虚拟机中&#xff0c;对象&#xff08;限于普通Java对象&#xff0c;不包括数组和Class对象等&#xff09;的创建又是怎样一个过…...

C基础-操作符详解

操作符分类&#xff1a; 算数操作符&#xff1a; - * / % //算数操作符 // int main() // { // // /除法 1.整数除法(除号两端都是整数) 2浮点数除法&#xff0c;除号的两端只要有一个小数就执行小数除法 // // 除法中&#xff0c;除数为0 // int a 7 / 2; /…...

时序预测 | MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元时间序列预测

时序预测 | MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元时间序列预测 目录 时序预测 | MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元时间序列预测效果一览基本介绍模型搭建程序设计参考资料 效果一览 基本介绍 MATLAB实现BO-BiGRU贝叶斯优化双向门控循环单元时间序列预测。…...

【深度学习实验】线性模型(五):使用Pytorch实现线性模型:基于鸢尾花数据集,对模型进行评估(使用随机梯度下降优化器)

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入库 1. 线性模型linear_model 2. 损失函数loss_function 3. 鸢尾花数据预处理 4. 初始化权重和偏置 5. 优化器 6. 迭代 7. 测试集预测 8. 实验结果评估 9. 完整代码 一、实验介…...

ADB底层原理

介绍 adb的全称为Android Debug Bridge&#xff0c;就是起到调试桥的作用。通过adb我们可以在Eclipse/Android Studio中方便通过DDMS来调试Android程序&#xff0c;说白了就是debug工具。adb是android sdk里的一个工具, 用这个工具可以直接操作管理android模拟器或者真实的and…...

etcd之读性能主要影响因素

1、Raft模块-线性读ReadIndex-节点之间的RTT延时、磁盘IO 线性读时Follower节点首先会向Raft 模块发送ReadIndex请求&#xff0c;此时Raft模块会先向各节点发送心跳确认&#xff0c;一半以上节点确认 Leader 身份后由leader节点将已提交日志索引 (committed index) 封装成 Rea…...

【Stable Diffusion】安装 Comfyui 之 window版

序言 由于stable diffusion web ui无法做到对流程进行控制&#xff0c;只是点击个生成按钮后&#xff0c;一切都交给AI来处理。但是用于生产生活是需要精细化对各个流程都要进行控制的。 故也就有个今天的猪脚&#xff1a;Comfyui 步骤 下载comfyui项目配置大模型和vae下载…...

Ansys Zemax | 如何建立二向分色分光镜

分光镜(Beam splitter)可被运用在许多不同的场合。一般而言&#xff0c;入射光抵达二向分色分光镜(dichroic beam splitter)时&#xff0c;会根据波长的差异产生穿透或反射的现象。这篇文章将说明如何在OpticStudio的非序列模式(non-sequential mode)中建立二向分色分光镜&…...

Mybatis学习笔记8 查询返回专题

1.返回实体类 2.返回List<实体类> 3.返回Map 4.返回List<Map> 5.返回Map<String,Map> 6.resultMap结果集映射 7.返回总记录条数 新建模块 依赖 目录结构 1.返回实体类 如果返回多条,用单个实体接收会出异常 2.返回List<实体类> 即使返回一条记…...

【测试开发】基础篇 · 专业术语 · 软件测试生命周期 · bug的描述 · bug的级别 · bug的生命周期 · 处理争执

【测试开发】基础篇 文章目录 【测试开发】基础篇1. 软件测试生命周期1.1 软件生命周期1.2 软件测试生命周期 2. 描述bug3. 如何定义bug的级别3.1 为什么要对bug进行级别划分3.2 bug的一些常见级别 4. bug的生命周期5. 产生争执这么怎么办&#xff08;处理人际关系&#xff09;…...

​bing许少辉乡村振兴战略下传统村落文化旅游设计images

​bing许少辉乡村振兴战略下传统村落文化旅游设计images...

第三十一章 Classes - 继承规则

第三十一章 Classes - 继承规则 继承规则 与其他基于类的语言一样&#xff0c;可以通过继承组合多个类定义。 类定义可以扩展&#xff08;或继承&#xff09;多个其他类。这些类又可以扩展其他类。 请注意&#xff0c;类不能继承 Python 中定义的类&#xff08;即 .py 文件中…...

华为云HECS安装docker并安装mysql

1、运行安装指令 yum install docker都选择y&#xff0c;直到安装成功 2、查看是否安装成功 运行版本查看指令&#xff0c;显示docker版本&#xff0c;证明安装成功 docker --version 3、启用并运行docker 3.1启用docker指令 systemctl enable docker 3.2 运行docker指令…...

MQ - 04 基础篇_存储_消息数据和元数据的存储设计

文章目录 导图概述元数据信息的存储消息数据的存储数据存储结构设计思路一 (Kafka的方案)思路二 (RocketMQ、RabbitMQ 和 Pulsar 的底层存储 BookKeeper 采用的方案)消息数据的分段实现根据偏移量定位根据索引定位 (RabbitMQ 和 RocketMQ的思路)使用场景消息数据存储格式…...

JavaScript:隐式转换、显示转换、隐式操作、显示操作

一、理解js隐式转换 JavaScript 中的隐式转换是指不需要显式地调用转换函数&#xff0c;而是在执行期间自动发生的数据类型的转换。即在使用不同类型的值进行操作时&#xff0c;JavaScript会自动进行类型转换。这种转换通常发生在不同数据类型之间进行运算或比较时。 序号分类…...

2023全新TwoNav开源网址导航系统源码 | 去授权版

2023全新TwoNav开源网址导航系统源码 已过授权 所有功能可用 测试环境&#xff1a;NginxPHP7.4MySQL5.6 一款开源的书签导航管理程序&#xff0c;界面简洁&#xff0c;安装简单&#xff0c;使用方便&#xff0c;基础功能免费。 TwoNav可帮助你将浏览器书签集中式管理&#…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

TJCTF 2025

还以为是天津的。这个比较容易&#xff0c;虽然绕了点弯&#xff0c;可还是把CP AK了&#xff0c;不过我会的别人也会&#xff0c;还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践

01技术背景与业务挑战 某短视频点播企业深耕国内用户市场&#xff0c;但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大&#xff0c;传统架构已较难满足当前企业发展的需求&#xff0c;企业面临着三重挑战&#xff1a; ① 业务&#xff1a;国内用户访问海外服…...