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

在这里插入图片描述

桥接设计模式

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

定义:

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

结构:

  • 抽象化(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.hqwc.cn/news/493237.html

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

相关文章

Spring Cloud与Docker集成:微服务容器化解决方案详解

推荐一款AI网站 AI写作与AI绘画智能创作平台 - 海鲸AI | 智能AI助手,可以免费领取GPT3.5无限卡 Spring Cloud 和 Docker 是两个不同的技术,但它们可以一起工作以构建、部署和管理微服务架构。下面是它们各自的简介以及它们如何协同工作的原理解析。 Sp…

路径属性---BGP的选路

一、路径属性 1、定义 路径属性:path attributes,作用类似于metric,用于度量BGP的路由优劣(用来进行选路) 2、分类 公认强制属性:所有的BGP的update消息都要包含该属性 AS路径(AS-path&#xff…

23年中科院1区算法|长鼻浣熊优化算法COA原理及其利用与改进(Matlab/Python)

文章来源于我的个人公众号:KAU的云实验台,主要更新智能优化算法的原理、应用、改进 CEC2005中的测试 本文 KAU将介绍一个2023年1月发表在中科院1区KBS上的优化算法——长鼻浣熊优化算法(Coati Optimization Algorithm,COA)[1] 该算法由Dehg…

开启数字内容创作的新时代

目录 技术解析 未来展望 技术解析 Sora是一款由OpenAI开发的先进AI视频模型,其技术架构基于深度学习和自然语言处理技术。该模型的核心算法原理包括使用深度神经网络进行视频内容的理解、生成和互动。 在技术架构方面,Sora采用了一种混合的神经网络结…

Elasticsearch 创建index库 timeout

问题概述 使用 python 客户端 代码进行创建,【之前成功创建,但是现在出现报错,报错代码es_connection.client.indices.create】def create_vector_index(dataset_index_name,vector_query_field,query_field):es_connection = get_collention(dataset_index_name,vector_que…

从零实现一套低代码(保姆级教程)【后端服务】 --- 【23】实现数据库表新增数据以及页面展示

摘要 在上一篇中,我们实现了可视化创建数据库表。并没说怎么对表中的数据进行操作。OK,现在我们来实现相关的内容。 如果说,对于新增数据我们无非有两种入口: 在AppBuilder中,可以通过可视化操作数据在XinBuilder中&…

小程序--vscode配置

要在vscode里开发微信小程序,需要安装以下两个插件: 安装后,即可使用vscode开发微信小程序。 注:若要实现鼠标悬浮提示,则需新建jsconfig.json文件,并进行配置,即可实现。 jsconfig.json内容如…

分披萨 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C 题目描述 “吃货”和“馋嘴”两人到披萨店点了一份铁盘(圆形)披萨,并嘱咐店员将披萨按放射状切成大小相同的偶数个小块。 但是粗心服务员将披萨切成了每块大小…

Qt RGB三色灯上位机

今天突发奇想做一个Qt RGB三色灯上位机,刚好手上有一个RGB三色灯和arduion开发板。 我是想实现一个颜色选择器界面然后鼠标点击颜色区域就可以发出rgb的值,然后把这个值通过串口线发送给arduion,arduion再解析出数据发送给RGB三色灯。 实现界面如下&…

免编程经验,搭建宠物店小程序轻松实现

在如今的互联网时代,小程序商城已成为各行业推广和销售的热门方式。对于花店来说,搭建一个自己的小程序商城不仅可以提升品牌形象,还可以方便顾客在线选购花卉产品。下面就来教大家如何轻松搭建一个花店小程序商城,并通过引流获得…

计网自顶向下:网络应用层【Web应用与HTTP协议】

目录 Web应用Web页URLWorld Wide Web 超文本传输协议——HTTP超文本C/S结构报文请求报文响应报文HTTP响应状态码try:在命令行里手工给web服务器发送请求 http连接的两种类型非持久(http1.0)持久(http1.1)▷ 流水线▷ 非…

基于yolov2深度学习网络的火焰烟雾检测系统matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 .................................................................. load yolov2.mat% 加载…