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

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

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

1. 概述

桥接模式(Bridge Pattern)是一种用于将抽象部分与其实现部分分离的结构型设计模式。这种模式通过组合关系而不是继承关系来连接抽象与实现,使代码更具扩展性和维护性。桥接模式的核心思想是将抽象和实现解耦,使得两者可以独立变化。

更多设计模式请参考:Java 中的 23 种设计模式详解

2. 模式结构

桥接模式包括以下几个部分:

  • 抽象部分(Abstraction):定义抽象接口,并持有一个指向实现部分对象的引用。
  • 精确抽象部分(Refined Abstraction):扩展抽象部分,增加具体功能。
  • 实现部分(Implementor):定义实现接口,提供基本操作的定义。
  • 具体实现部分(Concrete Implementor):具体实现 Implementor 接口,提供具体的操作实现。
3. 模式原理

桥接模式的原理是通过组合关系来代替继承关系,将抽象部分和实现部分分离,使得它们可以独立地变化。这样可以避免类的数量爆炸,提高代码的扩展性和维护性。具体来说:

  1. 抽象和实现分离:通过引入一个实现接口,使得抽象部分不直接依赖具体实现,而是依赖于接口。
  2. 独立变化:抽象部分和实现部分可以独立地变化和扩展,互不影响。
  3. 运行时绑定:在运行时,可以动态地将抽象部分和具体实现部分组合起来。
4. UML 类图
Abstraction+operation()-Implementor: ImplementorRefinedAbstraction+operation()Implementor+operationImpl()ConcreteImplementorA+operationImpl()ConcreteImplementorB+operationImpl()
5. 示例代码

我们以图形绘制为例,假设有不同类型的图形和不同的颜色。通过桥接模式,我们可以将图形和颜色分离,使它们可以独立变化。

Step 1: 定义实现接口 Color

// 实现接口,用于定义颜色的操作
public interface Color {void applyColor(); // 应用颜色的方法
}

Step 2: 实现具体的颜色 RedGreen

// 具体的红色实现类,实现 Color 接口
public class Red implements Color {@Overridepublic void applyColor() {System.out.println("Red color applied."); // 应用红色}
}// 具体的绿色实现类,实现 Color 接口
public class Green implements Color {@Overridepublic void applyColor() {System.out.println("Green color applied."); // 应用绿色}
}

Step 3: 定义抽象类 Shape

// 抽象类 Shape,持有一个 Color 类型的引用
public abstract class Shape {protected Color color; // 实现部分的引用// 构造函数,接受一个 Color 实现对象protected Shape(Color color) {this.color = color;}public abstract void draw(); // 抽象的绘制方法
}

Step 4: 实现具体的形状 CircleRectangle

// 具体的圆形实现类,扩展自 Shape
public class Circle extends Shape {public Circle(Color color) {super(color); // 调用父类构造函数}@Overridepublic void draw() {System.out.print("Circle drawn. "); // 输出图形信息color.applyColor(); // 应用颜色}
}// 具体的矩形实现类,扩展自 Shape
public class Rectangle extends Shape {public Rectangle(Color color) {super(color); // 调用父类构造函数}@Overridepublic void draw() {System.out.print("Rectangle drawn. "); // 输出图形信息color.applyColor(); // 应用颜色}
}

Step 5: 测试桥接模式

// 测试类,用于演示桥接模式的应用
public class BridgePatternDemo {public static void main(String[] args) {// 创建一个红色的圆形Shape redCircle = new Circle(new Red());// 创建一个绿色的矩形Shape greenRectangle = new Rectangle(new Green());// 绘制红色的圆形redCircle.draw();// 绘制绿色的矩形greenRectangle.draw();}
}
6. 输出
Circle drawn. Red color applied.
Rectangle drawn. Green color applied.
7. 优点
  • 分离抽象和实现:桥接模式将抽象和实现分离,提高了代码的扩展性和灵活性。
  • 遵循开闭原则:可以独立地扩展抽象部分和实现部分,不会影响现有代码。
  • 减少类的数量:通过组合而非继承,可以避免类的爆炸性增长。
8. 应用场景

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

  1. 多维度变化:当一个类存在多个独立变化的维度时,比如图形的形状和颜色,这些维度需要独立扩展和变化,可以使用桥接模式将这些维度分离,使它们可以独立变化。

    示例:假设我们有不同类型的图形(如圆形、矩形)和不同的颜色(如红色、绿色),可以将图形和颜色分离,使得它们可以独立变化。每增加一种图形或颜色,不需要修改现有代码,只需增加新的实现即可。

  2. 运行时绑定:当需要在运行时动态地改变抽象部分和实现部分的组合关系时,可以使用桥接模式。通过桥接模式,可以在运行时选择不同的实现,增强系统的灵活性。

    示例:假设我们有一个绘图应用程序,用户可以选择不同的绘图工具(如画笔、铅笔)和不同的绘图风格(如实线、虚线),可以使用桥接模式将绘图工具和绘图风格分离,使得用户可以在运行时动态选择不同的组合。

  3. 避免继承层次过多:当系统需要在多个维度上进行扩展,如果使用继承会导致类的爆炸性增长,可以使用桥接模式将这些维度分离,减少类的数量,避免继承层次过多。

    示例:假设我们有一个图形库,支持不同的图形(如圆形、矩形)和不同的绘图引擎(如OpenGL、DirectX),如果使用继承,每增加一种图形或绘图引擎,都需要增加多个类。使用桥接模式,可以将图形和绘图引擎分离,使得每增加一种图形或绘图引擎,只需增加一个新的实现类,减少类的数量。

9. 总结

桥接模式(Bridge Pattern)是一种结构型设计模式,旨在将抽象部分与其实现部分分离,从而使两者可以独立地变化。桥接模式通过组合关系代替继承关系,将抽象和实现解耦,使代码更具扩展性和维护性。它的核心思想是通过引入一个实现接口,使抽象部分不直接依赖具体实现,而是依赖于接口,从而达到独立扩展和运行时动态绑定的效果。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 《嵌入式 - 嵌入式大杂烩》ARM Cortex-M寄存器详解
  • 嵌入式初学-C语言-十六
  • elasticsearch--RestClient操作索引库(java)
  • linux查询占用端口 杀死占用端口进程
  • 基于OpenCV+MFC的视频读取与对象跟踪平台
  • MathType7.4中文版本功能详解!你的数学公式编辑神器
  • Conda Shell初始化指南:激活你的开发环境
  • RK3568平台开发系列讲解(文件系统篇)文件描述符 fd(File Descriptor)是什么?
  • 电脑自动重启是什么原因?重启原因排查和解决办法!
  • C++_sizeof的相关知识点
  • C++模板元一生之友之:std::enable_if
  • 若依vue版前端白名单处理
  • php之 进行签名公钥、私钥(SHA1withRSA签名)
  • oracle(19c)用户管理
  • pytorch学习笔记3 tensor索引和切片
  • Bytom交易说明(账户管理模式)
  • css的样式优先级
  • ECS应用管理最佳实践
  • JavaScript设计模式之工厂模式
  • markdown编辑器简评
  • mongodb--安装和初步使用教程
  • Mybatis初体验
  • PHP CLI应用的调试原理
  • redis学习笔记(三):列表、集合、有序集合
  • spring security oauth2 password授权模式
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 聚簇索引和非聚簇索引
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 我有几个粽子,和一个故事
  • 小程序开发之路(一)
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • ​ArcGIS Pro 如何批量删除字段
  • ​configparser --- 配置文件解析器​
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • (day6) 319. 灯泡开关
  • (八)Spring源码解析:Spring MVC
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (多级缓存)缓存同步
  • (二)Eureka服务搭建,服务注册,服务发现
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .net 无限分类
  • .NET企业级应用架构设计系列之技术选型
  • .net生成的类,跨工程调用显示注释
  • .Net实现SCrypt Hash加密
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • @PreAuthorize与@Secured注解的区别是什么?
  • @private @protected @public
  • [C++] new和delete