【深入理解设计模式】桥接设计模式

在这里插入图片描述

桥接设计模式

桥接设计模式是一种结构型设计模式,它旨在将抽象部分与实现部分分离,使它们可以独立变化,从而更好地管理复杂性。桥接模式通常涉及多个层次的抽象,其中一个层次(通常称为"抽象")依赖于另一个层次(通常称为"实现")的实例。

定义:

​ 将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

结构:

  • 抽象化(Abstraction)角色 :定义抽象类,并包含一个对实现化对象的引用。
  • 扩展抽象化(Refined Abstraction)角色 :是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
  • 实现化(Implementor)角色 :定义实现化角色的接口,供扩展抽象化角色调用,它可以是一个接口或一个抽象类。实现并不一定要与抽象完全匹配,但必须提供抽象所需的方法。
  • 具体实现化(Concrete Implementor)角色 :给出实现化角色接口的具体实现。

案例一:

// 实现部分接口
interface DrawingAPI {void drawCircle(double x, double y, double radius);
}// 具体实现部分A
class DrawingAPI1 implements DrawingAPI {@Overridepublic void drawCircle(double x, double y, double radius) {System.out.printf("API1.drawCircle at %f:%f radius %f%n", x, y, radius);}
}// 具体实现部分B
class DrawingAPI2 implements DrawingAPI {@Overridepublic void drawCircle(double x, double y, double radius) {System.out.printf("API2.drawCircle at %f:%f radius %f%n", x, y, radius);}
}// 抽象部分
abstract class Shape {protected DrawingAPI drawingAPI;protected Shape(DrawingAPI drawingAPI) {this.drawingAPI = drawingAPI;}public abstract void draw();
}// 扩充抽象部分
class Circle extends Shape {private double x, y, radius;public Circle(double x, double y, double radius, DrawingAPI drawingAPI) {super(drawingAPI);this.x = x;this.y = y;this.radius = radius;}@Overridepublic void draw() {drawingAPI.drawCircle(x, y, radius);}
}public class BridgePatternExample {public static void main(String[] args) {// 使用实现部分A来画一个圆Shape circle = new Circle(1, 2, 3, new DrawingAPI1());circle.draw();// 使用实现部分B来画一个圆Shape anotherCircle = new Circle(5, 7, 11, new DrawingAPI2());anotherCircle.draw();}
}

在上面的示例中,DrawingAPI 接口代表了实现部分,DrawingAPI1DrawingAPI2 分别是具体的实现部分。Shape 是抽象部分,Circle 是扩充抽象部分。在 Circle 类中,通过 drawingAPI 调用实现部分的方法来绘制圆。在 BridgePatternExample 类的 main 方法中,我们可以看到如何使用不同的实现部分来绘制不同的圆。

案例二:

【例】视频播放器

需要开发一个跨平台视频播放器,可以在不同操作系统平台(如Windows、Mac、Linux等)上播放多种格式的视频文件,常见的视频格式包括RMVB、AVI、WMV等。该播放器包含了两个维度,适合使用桥接模式。

类图如下:

/*** @author OldGj 2024/02/26* @version v1.0* @apiNote 视频文件 - 抽象实现化角色*/
public interface VideoFile {public void decode(String fileName);}
/*** @author OldGj 2024/02/26* @version v1.0* @apiNote RMVB类型的视频文件  - 具体实现化角色*/
public class RMVBFile implements VideoFile {@Overridepublic void decode(String fileName) {System.out.println("rmvb: " + fileName);}
}
/*** @author OldGj 2024/02/26* @version v1.0* @apiNote Avi格式的视频文件 - 具体实现化角色*/
public class AVIFile implements VideoFile{@Overridepublic void decode(String fileName) {System.out.println("avi : "+fileName);}
}
/*** @author OldGj 2024/02/26* @version v1.0* @apiNote 操作系统类 - 抽象化角色*/
public abstract class OperatingSystemVersion {//维护一个对实现的引用protected VideoFile videoFile;public OperatingSystemVersion(VideoFile videoFile) {this.videoFile = videoFile;}public abstract void play(String fileName);
}
/*** @author OldGj 2024/02/26* @version v1.0* @apiNote MAC操作系统 - 扩展抽象化角色*/
public class Mac extends OperatingSystemVersion{public Mac(VideoFile videoFile) {super(videoFile);}@Overridepublic void play(String fileName) {System.out.println("mac");videoFile.decode(fileName);}
}
/*** @author OldGj 2024/02/26* @version v1.0* @apiNote window操作系统 - 扩展抽象化角色*/
public class Window extends OperatingSystemVersion{public Window(VideoFile videoFile) {super(videoFile);}@Overridepublic void play(String fileName) {System.out.println("window");videoFile.decode(fileName);}
}
/*** @author OldGj 2024/02/26* @version v1.0* @apiNote 客户端 - 测试类*/
public class Client {public static void main(String[] args) {OperatingSystemVersion systemVersion = new Window(new RMVBFile());systemVersion.play("战狼");}
}

在这里插入图片描述

桥接模式是如何进行分离抽象和实现的?

假设我们要设计一个画图应用程序,它可以在不同的平台上绘制不同的形状,比如在 Windows 平台上绘制矩形和圆形,在 Linux 平台上绘制矩形和椭圆形。

首先,我们定义两个抽象类:ShapeDrawingAPI

// 抽象类 Shape
abstract class Shape {protected DrawingAPI drawingAPI;protected Shape(DrawingAPI drawingAPI) {this.drawingAPI = drawingAPI;}public abstract void draw(); // 抽象方法,绘制形状
}// 抽象类 DrawingAPI
interface DrawingAPI {void drawShape(); // 抽象方法,绘制形状
}

然后,我们定义具体的形状类,比如矩形和圆形,并且实现了 Shape 抽象类。

// 具体形状类 Rectangle
class Rectangle extends Shape {public Rectangle(DrawingAPI drawingAPI) {super(drawingAPI);}@Overridepublic void draw() {drawingAPI.drawShape(); // 调用实现部分的绘制方法}
}// 具体形状类 Circle
class Circle extends Shape {public Circle(DrawingAPI drawingAPI) {super(drawingAPI);}@Overridepublic void draw() {drawingAPI.drawShape(); // 调用实现部分的绘制方法}
}

接下来,我们实现两个不同的绘制API,比如在 Windows 平台和 Linux 平台上的绘制。

// 具体实现部分 DrawingAPI for Windows
class DrawingAPIWindows implements DrawingAPI {@Overridepublic void drawShape() {System.out.println("Drawing shape on Windows platform");}
}// 具体实现部分 DrawingAPI for Linux
class DrawingAPILinux implements DrawingAPI {@Overridepublic void drawShape() {System.out.println("Drawing shape on Linux platform");}
}

最后,我们在客户端代码中使用桥接模式来创建对象并调用方法。

public class BridgePatternExample {public static void main(String[] args) {// 在 Windows 平台上绘制矩形Shape rectangleWindows = new Rectangle(new DrawingAPIWindows());rectangleWindows.draw();// 在 Linux 平台上绘制圆形Shape circleLinux = new Circle(new DrawingAPILinux());circleLinux.draw();}
}

在这个例子中,抽象部分是 Shape 抽象类,具体形状类 RectangleCircle 是扩充抽象部分。实现部分是 DrawingAPI 接口,具体实现部分 DrawingAPIWindowsDrawingAPILinux 分别是不同平台上的具体实现。

通过使用桥接模式,我们成功地将抽象部分和实现部分分离开来,使它们可以独立变化。例如,如果要在 Windows 平台上绘制其他形状,只需创建一个新的具体形状类,并提供相应的 DrawingAPIWindows 实现即可,而不需要修改现有的代码。这种设计使得系统更加灵活、可扩展和易于维护。

桥接模式的优点包括:

  • 分离抽象和实现,使得它们可以独立变化,降低了系统的耦合度。
  • 提高了系统的可扩展性,可以方便地增加新的抽象和实现。
  • 提高了系统的可维护性,通过分离抽象和实现,减少了修改一个层次对另一个层次的影响。

使用场景

  • 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时
  • 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
  • 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。

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

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

相关文章

防御保护----内容安全

八.内容安全--------------------------。 IAE引擎: IAE引擎里面的技术:DFI和DPI技术--- 深度检测技术 DPI --- 深度包检测技术--- 主要针对完整的数据包(数据包分片,分段需要重组),之后对 数据包的内容进行…

【leetcode热题】三角形最小路径和

难度: 中等通过率: 37.6%题目链接:. - 力扣(LeetCode) 题目描述 给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。 例如,给定三角形: [[2],[3…

goland配置新增文件头

参考: goland函数注释生成插件 goland函数注释生成插件_goland自动加函数说明-CSDN博客 GoLand 快速添加方法注释 GoLand 快速添加方法注释_goland批量注释-CSDN博客 goland 如何设置头注释,自定义author和data goland 如何设置头注释,自定…

Web JavaScript

目录 1 前言2 原生js常见用法2.1 弹窗操作2.2 for循环操作2.3 打印日志操作2.4 获取页面值操作2.5 判空操作2.6 修改页面内容操作2.7 网页版计算器制作 3 外部js常见用法4 总结 1 前言 JavaScript 是一种脚本,一门编程语言,它可以在网页上实现复杂的功能…

事件循环解析

浏览器的进程模型 何为进程? 程序运行需要有它自己专属的内存空间,可以把这块内存空间简单的理解为进程 每个应用至少有一个进程,进程之间相互独立,即使要通信,也需要双方同意。 何为线程? 有了进程后&…

8.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-游戏底层功能对接类GameProc的实现

内容参考于:易道云信息技术研究院VIP课 上一个内容:通过逆向分析确定游戏明文接收数据过程 码云地址(master 分支):https://gitee.com/dye_your_fingers/titan 码云版本号:bcf7559184863febdcad819e48aa…

python number类型中的各种数学函数

python中的数学函数 函数返回值 ( 描述 )abs(x)返回数字的绝对值&#xff0c;如abs(-10) 返回 10ceil(x)返回数字的上入整数&#xff0c;如math.ceil(4.1) 返回 5cmp(x, y)如果 x < y 返回 -1, 如果 x y 返回 0, 如果 x > y 返回 1。Python 3 已废弃&#xff0c;使用 (…

QT信号槽实现分析

1.宏定义 qt中引入了MOC来反射&#xff0c;编译阶段变成 MOC–>预处理–>编译–>汇编–>链接 1-1、Q_OBJECT 这个宏定义了一系列代码&#xff0c;包括元对象和处理的函数 #define Q_OBJECT \public: \QT_WARNING_PUSH \Q_OBJECT_NO_OVERRIDE_WARNING \static c…

如何学习Arduino单片机

&#xff08;本文为简单介绍&#xff0c;内容源于网络&#xff09; 学习Arduino相关的网址和开源社区&#xff1a; Arduino官方文档: Arduino - HomeArduino Forum: Arduino ForumArduino Playground: Arduino Playground - HomePageGitHub: GitHub: Let’s build from here …

AE电源Apex Generator 系列5708009-C 使用说明 文件内容可以看目录,包含使用,调试,安装等内容都有160页

AE电源Apex Generator 系列5708009-C 使用说明 文件内容可以看目录&#xff0c;包含使用&#xff0c;调试&#xff0c;安装等内容都有160页

2.26 Qt day4+5 纯净窗口移动+绘画事件+Qt实现TCP连接服务+Qt实现连接数据库

思维导图 Qt实现TCP连接 服务器端&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTcpServer>//服务器端类 #include<QTcpSocket>//客户端类 #include<QMessageBox>//消息对话框类 #include<QList>//链…

亿道丨三防平板丨手持平板丨加固平板丨助力地震救援

自土耳其发生7.8级大地震以来&#xff0c;一直都牵动着世人的心。2023年2月10日&#xff0c;据法新社最新消息&#xff0c;强震已造成土耳其和叙利亚两国超2万人遇难。报道称&#xff0c;相关官员和医护人员表示&#xff0c;地震造成土耳其17674人死亡&#xff0c;叙利亚则有33…

Nginx+Tomcat实现动静分离

文章目录 一.动静分离的原理及架构1.1 动静分离是什么&#xff1f;1.2 动静分离的原理1.3 动静分离的架构组成 二.NginxTomcat实现动静分离2.1实验环境2.2所需软件环境2.3nginx服务的实现2.4配置动静分离 一.动静分离的原理及架构 1.1 动静分离是什么&#xff1f; 动静分离(S…

Nginx的核心配置指令及调优

目录 Nginx 核心配置指令 一、Nginx配置文件详解 1、配置文件目录 2、配置文件结构 二、调优 1、在全局域进行的调优 1.1线程池指令 1.2 工作进程数指令 1.3工作进程优先级指令 1.4 工作进程 CPU 绑定指令 1.5 调试可打开的文件个数 1.6 调试文件大小指令 1.7 只运…

FL Studio Fruity Edition2024中文入门版Win/Mac

FL Studio Fruity Edition2024是一款功能强大的音乐制作软件&#xff0c;适合初学者和音乐爱好者使用。它提供了丰富的音乐制作工具&#xff0c;包括音频录制、编辑、混音以及MIDI制作等功能&#xff0c;帮助用户轻松创作出动人的音乐作品。 FL Studio 21.2.3 Win-安装包下载如…

《数据治理简易速速上手小册》第1章 数据治理概述(2024 最新版)

文章目录 1.1 数据治理的定义与重要性1.1.1 基础知识1.1.2 重点案例&#xff1a;客户数据分析1.1.3 拓展案例 1&#xff1a;库存管理系统1.1.4 拓展案例 2&#xff1a;合规性数据报告 1.2 数据治理的发展历程1.2.1 基础知识1.2.2 重点案例&#xff1a;电商平台的用户数据管理1.…

苍穹外卖 -- day10- Spring Task- 订单状态定时处理- WebSocket- 来单提醒- 客户催单

苍穹外卖-day10 功能实现&#xff1a;订单状态定时处理、来单提醒和客户催单 订单状态定时处理&#xff1a; 来单提醒&#xff1a; 客户催单&#xff1a; 1. Spring Task 1.1 介绍 Spring Task 是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代…

稀疏表示分类(Sparse Representation for Classification,SRC)

稀疏表示分类&#xff08;Sparse Representation for Classification&#xff0c;简称SRC&#xff09;是一项在模式识别和信号处理中应用广泛的技术。它基于这样一个概念&#xff1a;一个信号&#xff08;比如图像、语音等&#xff09;可以用一个较大的字典中的一些基向量稀疏地…

SpringCache缓存专题

SpringCache缓存专题 学习目标 1、理解缓存存在的意义 2、掌握redis与SpringCache的集成方式 3、掌握SpringCache注解的使用 4、掌握项目集成SpringCache流程 第一章 基于SpringCache缓存方案 1.为什么需要缓存 ​ 前台请求&#xff0c;后台先从缓存中取数据&#xff0…