10结构型设计模式——桥接模式

一、桥接模式

桥接模式(Bridge Pattern)是结构型的设计模式之一。桥接模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来(解耦合),从而可以保持各部分的独立性以及应对它们的功能扩展。这个模式的关键在于提供一个桥梁,将抽象和具体的实现解耦,从而使得修改和扩展变得更为灵活。

桥接模式的结构图

桥接模式的组成

  1. 抽象类(Abstraction):定义高层次的操作接口,持有一个指向实现类的引用。
  2. 扩展抽象类(RefinedAbstraction):扩展抽象类的功能,但仍然依赖于抽象类定义的接口。
  3. 实现接口(Implementor):定义实现的接口,通常包括一些基本操作,不包括抽象层的操作。
  4. 具体实现类(ConcreteImplementor):实现Implementor(实现接口)的具体操作。

桥接模式的优点

  • 分离抽象与实现:允许在不影响抽象接口的情况下改变实现。
  • 增加灵活性:可以独立地扩展抽象和实现部分。
  • 提高可维护性:通过将功能分离,减少了代码的耦合性,使得维护和扩展更加容易。

二、桥接模式的应用场景 

  1. 需要将抽象和实现分离:当你有一个系统需要同时支持多个维度的变化,比如不同的抽象层次和不同的实现方式,桥接模式能够有效地将这两个维度解耦,使得修改和扩展变得更灵活。

  2. 避免在每个变化点创建大量的子类:如果一个系统中存在多个抽象层次和实现方式,直接继承组合会导致大量的子类产生。桥接模式通过分离抽象和实现,可以避免这种情况,使得系统结构更加简洁。

  3. 系统可能需要动态切换实现:当系统在运行时需要动态选择或切换不同的实现时,桥接模式提供了一种灵活的方式来管理这些实现,从而减少系统的复杂度。

  4. 需要提高系统的可扩展性:桥接模式允许在不影响其他部分的情况下独立地扩展抽象和实现部分。这对于希望在将来轻松地添加新的功能或实现的系统特别有用。

  5. 复杂的对象结构需要灵活的管理:当对象的结构非常复杂,例如,涉及到多个维度的变化时,桥接模式可以将这些维度分开管理,从而提高系统的可维护性和灵活性。

具体应用示例

  1. 图形绘制系统:在绘制不同类型的图形(如圆形、方形等)时,可以将图形的抽象(如如何绘制图形)和具体的绘制实现(如不同的绘图API)分开处理。例如,你可以使用桥接模式来支持不同的绘图API(如OpenGL、DirectX)和不同的图形(如圆形、矩形)组合。

  2. 用户界面(UI)框架:UI框架通常需要支持多个平台(如Windows、macOS、Linux)的具体实现,同时又要保持统一的用户界面设计。桥接模式可以将UI组件的抽象层(如按钮、文本框)与具体的平台实现分离开来,从而使得不同平台上的UI组件可以共享相同的抽象层。

  3. 跨平台开发:在需要跨多个操作系统或硬件平台的应用程序中,桥接模式可以用来将平台特定的实现与应用程序的核心逻辑分开,从而简化跨平台的开发和维护工作。

  4. 持久化层和数据库:当一个系统需要支持多种数据库(如MySQL、PostgreSQL、MongoDB)时,可以使用桥接模式将持久化层的抽象接口与具体的数据库实现分开,从而使得系统能够在不修改持久化逻辑的情况下,轻松切换或扩展数据库支持。

三、桥接模式的设计方法

 bridge.cpp

#include <iostream>
#include <string>// 定义平台接口
class DrawingAPI {
public:virtual void drawButton(const std::string& label, int x, int y, int width, int height) = 0;virtual void drawTextBox(const std::string& text, int x, int y, int width, int height) = 0;virtual ~DrawingAPI() = default;
};// 定义具体平台实现
class WindowsAPI : public DrawingAPI {
public:void drawButton(const std::string& label, int x, int y, int width, int height) override {std::cout << "Windows: Drawing button '" << label << "' at (" << x << ", " << y << ") with size " << width << "x" << height << std::endl;}void drawTextBox(const std::string& text, int x, int y, int width, int height) override {std::cout << "Windows: Drawing text box with text '" << text << "' at (" << x << ", " << y << ") with size " << width << "x" << height << std::endl;}
};class MacOSAPI : public DrawingAPI {
public:void drawButton(const std::string& label, int x, int y, int width, int height) override {std::cout << "MacOS: Drawing button '" << label << "' at (" << x << ", " << y << ") with size " << width << "x" << height << std::endl;}void drawTextBox(const std::string& text, int x, int y, int width, int height) override {std::cout << "MacOS: Drawing text box with text '" << text << "' at (" << x << ", " << y << ") with size " << width << "x" << height << std::endl;}
};class LinuxAPI : public DrawingAPI {
public:void drawButton(const std::string& label, int x, int y, int width, int height) override {std::cout << "Linux: Drawing button '" << label << "' at (" << x << ", " << y << ") with size " << width << "x" << height << std::endl;}void drawTextBox(const std::string& text, int x, int y, int width, int height) override {std::cout << "Linux: Drawing text box with text '" << text << "' at (" << x << ", " << y << ") with size " << width << "x" << height << std::endl;}
};// 定义UI组件的抽象层
class UIComponent {
public:UIComponent(DrawingAPI* api) : api_(api) {}virtual void draw() = 0;protected:DrawingAPI* api_;
};// 定义具体的UI组件
class Button : public UIComponent {
public:Button(const std::string& label, int x, int y, int width, int height, DrawingAPI* api): UIComponent(api), label_(label), x_(x), y_(y), width_(width), height_(height) {}void draw() override {api_->drawButton(label_, x_, y_, width_, height_);}private:std::string label_;int x_, y_, width_, height_;
};class TextBox : public UIComponent {
public:TextBox(const std::string& text, int x, int y, int width, int height, DrawingAPI* api): UIComponent(api), text_(text), x_(x), y_(y), width_(width), height_(height) {}void draw() override {api_->drawTextBox(text_, x_, y_, width_, height_);}private:std::string text_;int x_, y_, width_, height_;
};void doWorking() {WindowsAPI windowsAPI;MacOSAPI macOSAPI;LinuxAPI linuxAPI;Button windowsButton("Submit", 100, 50, 200, 40, &windowsAPI);TextBox windowsTextBox("Enter text", 100, 100, 300, 40, &windowsAPI);Button macButton("Submit", 100, 50, 200, 40, &macOSAPI);TextBox macTextBox("Enter text", 100, 100, 300, 40, &macOSAPI);Button linuxButton("Submit", 100, 50, 200, 40, &linuxAPI);TextBox linuxTextBox("Enter text", 100, 100, 300, 40, &linuxAPI);std::cout << "Drawing Windows UI components:" << std::endl;windowsButton.draw();windowsTextBox.draw();std::cout << "\nDrawing MacOS UI components:" << std::endl;macButton.draw();macTextBox.draw();std::cout << "\nDrawing Linux UI components:" << std::endl;linuxButton.draw();linuxTextBox.draw();return ;
}int main() {// start workingdoWorking();return 0;
}

运行效果

四、总结

在这个示例中:

  • DrawingAPI 是平台接口,定义了绘制方法。
  • WindowsAPI 和 MacOSAPI 、LinuxAPI 是具体实现,提供平台特定的绘制方法。
  • UIComponent 是抽象层,持有DrawingAPI 的引用。
  • Button 和 TextBox 是具体的UI组件,实现了 UIComponent 。

桥接模式通过分离抽象和实现,使得UI组件的抽象层可以与不同的平台实现解耦,从而使得支持新平台或修改现有平台的实现变得更加容易。

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

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

相关文章

SystemUI下拉框新增音量控制条

Android产品下拉框一直只有亮度条没有音量控制条。 为了方便控制音量&#xff0c;普遍都是底部导航栏添加音量加减按钮&#xff0c;在Android10以后&#xff0c;大家普遍用上了手势导航&#xff0c;去掉底部导航栏。 目前需要再下拉框中可以直接控制音量。 文章目录 前言需求及…

day33

一、linux系统中的库 库在linux系统中是一个二进制文件&#xff0c;它是由XXX.c&#xff08;不包含main函数&#xff09;文件编译而来的&#xff0c;分为静态库和动态库。 库在系统中的内容是不可见的&#xff0c;是一个二进制乱码 当程序需要使用库中的相关函数时&#xff0c;…

安装docker 遇到异常Could not resolve host: mirrorlist.centos.org; 未知的错误

问题 安装docker 遇到异常 Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx86_64&repoos&infrastock error was 14: curl#6 - “Could not resolve host: mirrorlist.centos.org; 未知的错误” 1、安装Docker依赖包 yum install …

基于SpringBoot的论坛系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图详细视频演示技术栈系统测试为什么选择我官方认证玩家&#xff0c;服务很多代码文档&#xff0c;百分百好评&#xff0c;战绩可查&#xff01;&#xff01;入职于互联网大厂&#xff0c;可以交流&#xff0c;共同进步。有保障的售后 代码参考数据库参…

Android 12系统源码_多屏幕(二)模拟辅助设备功能开关实现原理

前言 上一篇我们通过为Android系统开启模拟辅助设备功能开关&#xff0c;最终实现了将一个Activity显示到多个屏幕的效果。 本篇文章我们具体来分析一下当我们开启模拟辅助设备功能开关的时候&#xff0c;Android系统做了什么哪些操作。 一、模拟辅助设备功能开关应用位置 …

存储实验:华为异构存储在线接管与在线数据迁移(Smart Virtualization Smart Migration 特性)

目录 目的实验环境实验步骤参考文档1. 主机安装存储多路径2. v2存储创建Lun&#xff0c;映射给主机&#xff1b;主机分区格式化&#xff0c;写数据3. 将v2存储映射该成映射到v3存储上(v3存储和v2之间链路搭建&#xff0c;测通&#xff0c;远端设备&#xff09;&#xff08;Smar…

便利店(超市)管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图详细视频演示技术栈系统测试为什么选择我官方认证玩家&#xff0c;服务很多代码文档&#xff0c;百分百好评&#xff0c;战绩可查&#xff01;&#xff01;入职于互联网大厂&#xff0c;可以交流&#xff0c;共同进步。有保障的售后 代码参考数据库参…

中国:“虚拟资产”交易被列为公认的洗钱方式之一!最高法院承认加密货币交易!

2024年8月19日&#xff0c;最高人民法院和最高人民检察院表示&#xff0c;根据他们对反洗钱法的新解释&#xff0c;“虚拟资产”交易现已被列为公认的洗钱方式之一。这是中国首次针对此类资产类别采取此类举措&#xff0c;说明为应对加密货币和其他虚拟资产日益增长的使用&…

IO进程线程8.20

1.使用fgets获取文件的行号 #include <myhead.h> int main(int argc, const char *argv[]) {FILE *fp fopen("./1.txt","r");if(fpNULL){perror("fp");return -1;}char buf[30];int count 0;while(fgets(buf,sizeof(buf),fp)){count;}p…

为IntelliJ IDEA安装插件

安装插件 插件是开发工具的扩展程序&#xff0c;通常由第三方提供&#xff0c;当安装了插件后&#xff0c;原开发工作的菜单、按钮等开发环境可能会发生变化&#xff0c;例如出现了新的菜单项&#xff0c;或出现了新的按钮&#xff0c;甚至一些全新的编码方式&#xff0c;通常…

双向链表复习(C语言版)

目录 链表分类&#xff1a; 双向链表初始化&#xff1a; 双向链表的插入&#xff1a; 双向链表的打印&#xff1a; 双向链表的删除&#xff1a; 双向链表的指定结点位置查找&#xff1a; 双向链表的在指定位置之后插入数据&#xff1a; 注意&#xff1a;通过上文的指定…

地理科学专业| 中国大学排行榜(2024年)

地理科学专业| 中国大学排行榜&#xff08;2024年&#xff09;

客车制造5G智能工厂工业物联数字孪生平台,推进制造业数字化转型

制造业正经历着前所未有的变革&#xff0c;其中客车制造行业作为传统制造业的重要组成部分&#xff0c;正积极拥抱5G、工业物联网及数字孪生等先进技术&#xff0c;推动生产模式的全面升级与数字化转型。 客车制造5G智能工厂工业物联数字孪生平台的出现&#xff0c;不仅为行业…

【Linux】系列入门摘抄笔记-8-权限管理chmod/chown

Linux操作系统中文件的基本权限由9个字符组成&#xff0c;分别为属主、属组和其他用户&#xff0c;用于规定是否对文件有读、写和执行权限。 文件/目录的权限与归属 目录列表中&#xff0c;有9列 第一列&#xff1a;文件类型与权限&#xff08;共10个字符&#xff0c;分为四组…

电子木鱼+提肛+游戏地图,车机还能这么玩?

文/王俣祺 导语&#xff1a;电子木鱼、提肛训练、游戏级地图&#xff0c;你很难想象这些“直男关怀”是来自小鹏MONA M03的车机系统。最近&#xff0c;一批关于MONA M03车机功能的视频在网上疯传&#xff0c;一系列“没用但有趣”的功能广受年轻用户的好评&#xff0c;情绪价值…

linux上用anaconda创建一个新环境,并将nicegui的应用打包为一个可执行应用

先下载好anaconda linux版本 Download Anaconda Distribution | Anacondahttps://www.anaconda.com/download/之后运行 conda create --name py311 python3.11 --name py311 是环境名 python3.11 是python版本 安装完成后&#xff0c;运行 conda env list 得到 这时我们…

手机使用技巧:如何恢复Android手机不见的短信

在您的 Android 手机上丢失短信可能是一种令人沮丧的经历&#xff0c;尤其是在文本包含重要信息的情况下。幸运的是&#xff0c;有一些方法可以在Android上恢复已删除的短信。在这篇博文中&#xff0c;我们将讨论几种在Android手机上恢复已删除短信的方法。 为什么需要恢复Andr…

【python】逐步回归(多元线性回归模型中的应用)

文章目录 前言一、逐步回归1. 前进法&#xff08;Forward Selection&#xff09;2. 后退法&#xff08;Backward Elimination&#xff09;3. 逐步回归法&#xff08;Stepwise Regression&#xff09; 二、示例三、代码实现----python 前言 Matlab中逐步回归的实现可以使用 Mat…

软体水枪在灭火工作中发挥什么作用_鼎跃安全

火灾&#xff0c;这一频繁侵袭我们日常生活的灾难性事件&#xff0c;以其迅猛之势对人类的生存环境与日常生活构成了极其严重的破坏与威胁。它不仅能够在瞬间吞噬财产&#xff0c;更可怕的是&#xff0c;它无情地剥夺了生命&#xff0c;破坏了家庭&#xff0c;给社会留下了难以…

关于Ubuntu中使用命令行安装Qt的一些分享

以Ubuntu 22.04为例。 1、安装默认的Qt库 sudo apt-get install qtbase5-dev qtbase5-dev-tools qtchooser 这条指令执行完会出现 usr/lib/x86_64-linux-gnu/qt5 文件&#xff0c;并伴随5个子文件夹&#xff0c;结构如下&#xff1a; 并且会出现 usr/lib/qt5, usr/lib/x86_6…