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

二十三种设计模式-桥接模式

桥接模式(Bridge Pattern)是一种结构型设计模式,其核心思想是将抽象与实现解耦,让它们可以独立变化。桥接模式主要用于解决类的继承问题,避免由于继承而带来的类层次结构过于复杂和难以维护的问题。

1. 核心概念

桥接模式通过引入一个“桥接类”(Bridge),将抽象部分(Abstraction)与实现部分(Implementation)分离,使得它们可以独立地变化。具体来说:

  • 抽象部分(Abstraction):定义了客户端使用的接口,通常包含一个指向实现部分的引用。

  • 实现部分(Implementation):定义了实现的具体细节,通常是一个接口或抽象类。

  • 桥接类(Bridge):将抽象部分与实现部分连接起来,允许它们独立变化。

2. 应用场景

桥接模式适用于以下场景:

  • 当一个类存在两个独立变化的维度时(例如,抽象和实现)。

  • 当不希望使用继承的方式将抽象和实现绑定在一起时。

  • 当需要对抽象和实现进行独立扩展时。

3. 示例代码

以下是一个典型的桥接模式的实现示例:

3.1 定义实现部分(Implementation)
// 实现部分的接口
interface Implementor {void operationImplementor();
}// 具体实现类 A
class ConcreteImplementorA implements Implementor {@Overridepublic void operationImplementor() {System.out.println("ConcreteImplementorA: Implementing operation");}
}// 具体实现类 B
class ConcreteImplementorB implements Implementor {@Overridepublic void operationImplementor() {System.out.println("ConcreteImplementorB: Implementing operation");}
}
3.2 定义抽象部分(Abstraction)
// 抽象部分
abstract class Abstraction {protected Implementor implementor; // 桥接:包含一个实现部分的引用// 设置实现部分public void setImplementor(Implementor implementor) {this.implementor = implementor;}public abstract void operation();
}
3.3 定义具体抽象类(RefinedAbstraction)
// 具体抽象类
class RefinedAbstraction extends Abstraction {@Overridepublic void operation() {System.out.println("RefinedAbstraction: Delegating operation to Implementor");implementor.operationImplementor(); // 调用实现部分的方法}
}
3.4 客户端代码
public class BridgePatternDemo {public static void main(String[] args) {// 创建具体实现类Implementor implementorA = new ConcreteImplementorA();Implementor implementorB = new ConcreteImplementorB();// 创建具体抽象类Abstraction abstraction = new RefinedAbstraction();// 设置实现部分为 A 并调用操作abstraction.setImplementor(implementorA);abstraction.operation();// 更改实现部分为 B 并调用操作abstraction.setImplementor(implementorB);abstraction.operation();}
}

4. 输出结果

运行上述代码后,输出结果如下:

RefinedAbstraction: Delegating operation to Implementor
ConcreteImplementorA: Implementing operation
RefinedAbstraction: Delegating operation to Implementor
ConcreteImplementorB: Implementing operation

5. 优点

  • 分离抽象与实现:客户端使用的抽象接口与后台的具体实现完全独立,可以独立地变化。

  • 扩展性好:可以独立地扩展抽象部分和实现部分,而无需修改另一部分的代码。

  • 减少子类数量:避免了由于多维继承带来的类爆炸问题。

6. 缺点

  • 增加系统复杂度:引入了额外的类,可能会使系统结构变得复杂。

  • 需要维护桥接关系:需要确保抽象部分和实现部分之间的桥接关系正确,否则可能导致运行时错误。

7. 实际应用

桥接模式在Java标准库中也有广泛的应用,例如:

  • java.util.Listjava.util.ArrayListList 是抽象接口,ArrayList 是具体实现类,通过桥接模式实现了接口与实现的分离。

  • java.io.InputStreamjava.io.FileInputStreamInputStream 是抽象类,FileInputStream 是具体实现类,通过桥接模式实现了抽象与实现的解耦。

桥接模式是一种非常灵活且强大的设计模式,尤其适用于需要分离抽象和实现的场景。

桥接模式的应用广泛性

桥接模式是一种经典的设计模式,被广泛应用于软件开发领域。它在许多开发框架和库中都有应用,例如Java中的AWT和Swing框架。此外,桥接模式也常与其他设计模式结合使用,以提高系统的可扩展性、灵活性和可维护性。

实际应用场景

  1. 消息通知系统
    在一个消息通知系统中,支持多种通知方式(如邮件、短信、微信等)和多种紧急程度(如普通、紧急、严重等)。通过桥接模式,可以将通知方式和紧急程度分离,使得两者可以独立扩展。

  2. 汽车引擎安装系统
    在一个汽车引擎安装系统中,支持多种汽车品牌(如奔驰、宝马等)和多种引擎类型(如200型、300型等)。通过桥接模式,可以将汽车品牌和引擎类型分离,使得两者可以独立扩展。

  3. 图形界面库
    在图形界面库中,桥接模式可以用于控件和主题的组合。例如,一个按钮控件可以有不同的显示风格(如Windows风格、Mac风格等),通过桥接模式可以将按钮的逻辑与显示风格分离。

  4. 数据库访问层
    在数据库访问层中,桥接模式可以用于数据库连接和数据库驱动的组合。例如,一个数据访问对象(DAO)可以使用不同的数据库连接实现(如JDBC连接、Hibernate连接等),通过桥接模式可以将DAO逻辑与具体的数据库连接实现分离。

  5. 消息传输协议
    在消息传输协议中,消息内容和传输方式可以作为两个独立的维度。通过桥接模式,可以实现不同消息和传输方式的组合,而无需修改消息传输协议的代码。

  6. 音频和视频播放器
    在音频和视频播放器中,播放器逻辑和解码器实现可以作为两个独立的维度。通过桥接模式,可以将播放器逻辑与具体的解码器实现分离,使得两者可以独立扩展。

  7. 支付系统
    在支付系统中,支付渠道(如微信支付、支付宝)和支付方式(如扫码支付、密码支付、人脸支付等)可以作为两个独立的维度。通过桥接模式,可以将支付渠道和支付方式分离,使得两者可以独立扩展。

桥接模式的优势

桥接模式的主要优势在于:

  • 分离抽象与实现:抽象部分和实现部分可以独立变化,符合开闭原则。

  • 减少类的数量:避免了由于多维继承导致的类爆炸问题。

  • 提高系统的可扩展性:可以在不修改现有代码的情况下,新增新的抽象和实现类。

  • 促进代码重用:通过组合的方式实现复用,降低了代码的冗余度。

使用桥接模式的注意事项

  • 桥接模式适用于多个独立变化的维度,如果只有一两个维度的变化,使用继承可能更简单。

  • 桥接模式会增加系统的复杂度,需要谨慎使用。

  • 需要正确选择和使用抽象类和接口,避免过度抽象或过于具体化。

总的来说,桥接模式在实际项目中应用广泛,尤其是在需要处理多个独立变化维度的场景中。它能够显著提高系统的灵活性、可扩展性和可维护性。

相关文章:

二十三种设计模式-桥接模式

桥接模式(Bridge Pattern)是一种结构型设计模式,其核心思想是将抽象与实现解耦,让它们可以独立变化。桥接模式主要用于解决类的继承问题,避免由于继承而带来的类层次结构过于复杂和难以维护的问题。 1. 核心概念 桥接…...

jenkins-k8s pod方式动态生成slave节点

一. 简述: 使用 Jenkins 和 Kubernetes (k8s) 动态生成 Slave 节点是一种高效且灵活的方式来管理 CI/CD 流水线。通过这种方式,Jenkins 可以根据需要在 Kubernetes 集群中创建和销毁 Pod 来执行任务,从而充分利用集群资源并实现更好的隔离性…...

代码工艺:实践 Spring Boot TDD 测试驱动开发

TDD 的核心理念是 “先写测试,再写功能”,其过程遵循一个严格的循环,即 Red-Green-Refactor: TDD 的流程 1. Red(编写失败的测试) 根据需求,先编写一个测试用例,描述期望的行为。…...

【云安全】云原生-K8S-简介

K8S简介 Kubernetes(简称K8S)是一种开源的容器编排平台,用于管理容器化应用的部署、扩展和运维。它由Google于2014年开源并交给CNCF(Cloud Native Computing Foundation)维护。K8S通过提供自动化、灵活的功能&#xf…...

aws(学习笔记第二十六课) 使用AWS Elastic Beanstalk

aws(学习笔记第二十六课) 使用aws Elastic Beanstalk 学习内容: AWS Elastic Beanstalk整体架构AWS Elastic Beanstalk的hands onAWS Elastic Beanstalk部署node.js程序包练习使用AWS Elastic Beanstalk的ebcli 1. AWS Elastic Beanstalk整体架构 官方的guide AWS…...

反向代理模块。。

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说,反向代理就相当于…...

C语言的灵魂——指针(1)

指针是C语言的灵魂,有了指针C语言才能完成一些复杂的程序;没了指针就相当于C语言最精髓的部分被去掉了,可见指针是多么重要。废话不多讲我们直接开始。 指针 一,内存和地址二,编址三,指针变量和地址1&#…...

14-6-2C++STL的list

(一&#xff09;list对象的带参数构造 1.list&#xff08;elem);//构造函数将n个elem拷贝给本身 #include <iostream> #include <list> using namespace std; int main() { list<int> lst(3,7); list<int>::iterator it; for(itlst.begi…...

Linux 基础1

gcc的编译过程 预处理——编译——汇编——链接 Linux文件类型 普通文件&#xff0c;目录文件&#xff0c;管道文件&#xff0c;链接文件&#xff0c;块设备文件&#xff0c;字符设备文件&#xff0c;套接字文件 Linux系统下的软链接和硬链接有什么异同 linux中软链接和硬…...

Ubuntu Server 安装 XFCE4桌面

Ubuntu Server没有桌面环境&#xff0c;一些软件有桌面环境使用起来才更加方便&#xff0c;所以我尝试安装桌面环境。常用的桌面环境有&#xff1a;GNOME、KDE Plasma、XFCE4等。这里我选择安装XFCE4桌面环境&#xff0c;主要因为它是一个极轻量级的桌面环境&#xff0c;适合内…...

xarray转换nc文件经度范围:0-360更改为-180-180

原文见https://blog.csdn.net/weixin_44237337/article/details/119707332&#xff0c;因为觉得很实用就转载一下。 lon_name longitude #你的nc文件中经度的命名 ds[longitude_adjusted] xr.where(ds[lon_name] > 180,ds[lon_name] - 360,ds[lon_name]) ds (ds.swap_d…...

MySQL 基础学习(1):数据类型与操作数据库和数据表

MySQL 基础学习&#xff1a;数据类型与操作数据库和数据表 在这篇博客中&#xff0c;我们将深入学习 MySQL 的基础操作&#xff0c;重点关注数据库和数据表的操作&#xff0c;以及 MySQL 中常见的数据类型。希望本文能帮助你更好地理解和掌握 MySQL 的基本用法。 一、操作数据…...

一个简单的自适应html5导航模板

一个简单的 HTML 导航模板示例&#xff0c;它包含基本的导航栏结构&#xff0c;同时使用了 CSS 进行样式美化&#xff0c;让导航栏看起来更美观。另外&#xff0c;还添加了一些 JavaScript 代码&#xff0c;用于在移动端实现导航菜单的展开和收起功能。 PHP <!DOCTYPE htm…...

深入解析“Wholesome”的含义及用法

深入解析“Wholesome”的含义及用法 一、引言 在阅读英文材料时&#xff0c;我们经常会遇到一些词汇&#xff0c;它们的含义既有直接的字面意思&#xff0c;又带有丰富的情感色彩。“Wholesome”就是这样一个词。它表面上看似简单&#xff0c;但在不同语境中却有多重内涵。在…...

供水企业满意度调查报告

民安智库作为一家独立的第三方评估机构&#xff0c;致力于为供水企业提供全面的客户满意度调查服务。本报告将详细介绍民安智库的调查方法、结果和建议&#xff0c;以帮助供水企业更好地理解其服务质量和客户需求。 一、调查方法 民安智库首先对客户进行了分类&#xff0c;包括…...

实现B-树

一、概述 1.历史 B树&#xff08;B-Tree&#xff09;结构是一种高效存储和查询数据的方法&#xff0c;它的历史可以追溯到1970年代早期。B树的发明人Rudolf Bayer和Edward M. McCreight分别发表了一篇论文介绍了B树。这篇论文是1972年发表于《ACM Transactions on Database S…...

无人机微波图像传输数据链技术详解

无人机微波图像传输数据链技术是无人机通信系统中的关键组成部分&#xff0c;它确保了无人机与地面站之间高效、可靠的图像数据传输。以下是对该技术的详细解析&#xff1a; 一、技术原理 无人机微波图像传输数据链主要基于微波通信技术实现。在数据链路中&#xff0c;图像数…...

【Leetcode 热题 100】300. 最长递增子序列

问题背景 给你一个整数数组 n u m s nums nums&#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c; [ 3 , 6 , 2 , 7 ] [3,6,2,7] [3,6,2…...

macos的图标过大,这是因为有自己的设计规范

苹果官方链接&#xff1a;App 图标 | Apple Developer Documentation 这个在官方文档里有说明&#xff0c;并且提供了sketch 和 ps 的模板。 figma还提供了模板&#xff1a; Figma...

信号处理以及队列

下面是一个使用C和POSIX信号处理以及队列的简单示例。这个示例展示了如何使用信号处理程序将信号放入队列中&#xff0c;并在主循环中处理这些信号。 #include <iostream> #include <csignal> #include <queue> #include <mutex> #include <thread…...

微信阅读网站小程序的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

美国公司有意收购TikTok(抖音)

众所周知&#xff0c;2016年TikTok由字节跳动集团推出&#xff0c;最初以“抖音”为名在中国市场推广&#xff0c;随后于2017年下半年出海&#xff0c;面向国际市场更名为“TikTok”。 新华社1月19日快讯&#xff1a;“TikTok公司当地时间18日晚通知美国用户&#xff0c;由于美…...

《Java程序设计》课程考核试卷

一、单项选择题&#xff08;本大题共10个小题&#xff0c;每小题2分&#xff0c;共20分&#xff09; 1.下列用来编译Java源文件为字节码文件的工具是&#xff08; &#xff09;。 A.java B.javadoc C.jar D.javac 2…...

ThinkPHP 8 操作JSON数据

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 编程与应用开…...

《AI赋能光追:开启图形渲染新时代》

光线追踪技术是图形渲染领域的重大突破&#xff0c;能够通过模拟光的传播路径&#xff0c;精准渲染反射、折射、阴影和间接光照等效果&#xff0c;实现高度逼真的场景呈现。而人工智能的加入&#xff0c;更是为光线追踪技术带来了前所未有的变革&#xff0c;主要体现在以下几个…...

LeetCode | 最小路径和的两种解决办法

第一种&#xff1a;动态规划 思路 在过去&#xff0c;有这样一个词&#xff0c;那就是遇难则反&#xff0c;从起点推导出最小路径和是困难的&#xff0c;那我们就从终点去推导。 解题过程 我们都知道一个方块&#xff0c;只能向右或向下。在初始化dp之后&#xff0c;我们会…...

Windows 环境下 Docker Desktop + Kubernetes 部署项目指南

Windows 环境下 Docker Desktop Kubernetes 部署项目指南 一、环境准备二、安装与配置 Kubernetes安装 windows 版的 docker启动 kubernetes安装 windows 版的 kubectl 工具下载 k8s-for-docker-desktop启动 Kubernetes Dashboard 二、在 Kubernetes 上部署项目创建一个 demo …...

WebSocket 详解:全双工通信的实现与应用

目录 一、什么是 WebSocket&#xff1f;&#xff08;简介&#xff09; 二、为什么需要 WebSocket&#xff1f; 三、HTTP 与 WebSocket 的区别 WebSocket 的劣势 WebSocket 的常见应用场景 WebSocket 握手过程 WebSocket 事件处理和生命周期 一、什么是 WebSocket&#xf…...

神经网络|(二)sigmoid神经元函数

【1】引言 在前序学习进程中&#xff0c;我们已经了解了基本的二元分类器和神经元的构成&#xff0c;文章学习链接为&#xff1a; 神经网络|(一)加权平均法&#xff0c;感知机和神经元-CSDN博客 在此基础上&#xff0c;我们认识到神经元本身在做二元分类&#xff0c;是一种非…...

云原生:构建现代化应用的基石

一、什么是云原生&#xff1f; 云原生是一种构建和运行应用程序的方法&#xff0c;旨在充分利用云计算的分布式系统优势&#xff0c;例如弹性伸缩、微服务架构、容器化技术等。云原生应用程序从设计之初就考虑到了云环境的特点&#xff0c;能够更好地适应云平台的动态变化&…...