设计模式-11 - Bridge Method 桥接模式

设计模式-11 - Bridge Method 桥接模式

1.定义

桥接模式是一种设计模式,它将抽象部分与其实现部分分离,使它们可以独立变化。它允许你改变抽象部分和实现部分的实现,而无需更改它们的接口。
结构:

桥接模式涉及四个主要角色:

  • 抽象(Abstraction):定义抽象接口,客户端代码与之交互。
  • 实现(Implementor):实现抽象接口并提供具体行为。
  • 扩展抽象(Refined Abstraction):扩展抽象接口,提供更加具体的接口。
  • 具体实现(Concrete Implementor):实现扩展抽象接口并提供具体的实现。

一个常见的桥接模式示例是图形绘制库。抽象接口可以定义绘制不同形状的方法,而实现对象可以提供不同平台(例如 Windows 或 macOS)的具体绘制实现。这允许开发人员使用相同的抽象接口在不同平台上绘制形状,而无需更改代码。


2.内涵

桥接模式工作原理

  • 客户端代码通过抽象接口与桥接模式交互。
  • 抽象接口将请求委托给实现对象。
  • 实现对象执行请求并返回结果。
  • 桥接模式允许在不改变抽象接口的情况下改变实现。
  • 还可以扩展抽象接口和具体实现,以提供新的功能或行为。

桥接模式核心组件及调用关系 ASCII 图

+----------------+| Abstraction    |+----------------+|v+-----------------------+------------------+| RefinedAbstraction1 | RefinedAbstraction2 |+--------------+-----------------------------+|                  |v                  v+--------------+           +--------------+| ConcreteImplementor1 |  | ConcreteImplementor2 |+--------------+           +--------------+


调用关系:

客户端代码通过 RefinedAbstraction 类与 Abstraction 类进行交互。
RefinedAbstraction 类将调用委托给其关联的 ConcreteImplementor 类。
组件说明:

Abstraction:定义抽象接口,它定义了客户端代码与桥接模式交互的方式。
RefinedAbstraction:扩展 Abstraction 接口,为特定的实现提供不同的行为。
ConcreteImplementor:实现 Abstraction 接口,提供具体的实现细节。

           
3.使用示例
#include <iostream>// Abstraction: Shape
class Shape {
public:virtual void draw() = 0;
};// Implementations: Renderer (VectorRenderer and
// RasterRenderer)
class Renderer {
public:virtual void render() = 0;
};class VectorRenderer : public Renderer {
public:void render() override{std::cout << "Rendering as a vector\n";}
};class RasterRenderer : public Renderer {
public:void render() override{std::cout << "Rendering as a raster\n";}
};// Concrete Abstractions: Circle and Square
class Circle : public Shape {
public:Circle(Renderer& renderer): renderer(renderer){}void draw() override{std::cout << "Drawing a circle ";renderer.render();}private:Renderer& renderer;
};class Square : public Shape {
public:Square(Renderer& renderer): renderer(renderer){}void draw() override{std::cout << "Drawing a square ";renderer.render();}private:Renderer& renderer;
};int main()
{VectorRenderer vectorRenderer;RasterRenderer rasterRenderer;Circle circle(vectorRenderer);Square square(rasterRenderer);circle.draw(); // Output: Drawing a circle Rendering as// a vectorsquare.draw(); // Output: Drawing a square Rendering as// a rasterreturn 0;
}

4.注意事项

桥接模式注意事项:

  • 复杂性:桥接模式引入了额外的抽象层,这可能会增加代码的复杂性。
  • 性能开销:在桥接模式中,抽象类和具体实现类之间的调用可能引入性能开销。
  • 过度设计:在某些情况下,桥接模式可能被过度使用,导致不必要的复杂性。
  • 多重继承的替代方案:在某些语言中,多重继承可以提供与桥接模式类似的功能,但可能更简单且性能更高。
  • 接口的稳定性:桥接模式依赖于稳定的抽象接口。如果接口经常更改,则可能会导致应用程序不稳定。


何时使用桥接模式:

  • 当你需要在不改变抽象部分的情况下改变实现部分时。
  • 当你想要将不同类型的实现封装在统一的接口后面时。
  • 当你想在多个平台或环境中使用相同的抽象接口时。


何时不使用桥接模式:

  • 当抽象部分和实现部分之间没有明确的分离时。
  • 当性能开销不可接受时。
  • 当代码的复杂性已经很高时。

5.最佳实践

桥接模式最佳实践:

  • 明确分离抽象和实现:确保抽象接口只定义高级概念,而具体实现提供具体的实现细节。
  • 保持抽象接口稳定:避免经常更改抽象接口,因为这可能会破坏依赖于该接口的代码。
  • 使用组合而非继承:桥接模式通常使用组合而不是继承来实现分离,这提供了更大的灵活性。
  • 避免过度使用:只有在确实需要在不更改抽象的情况下更改实现时才使用桥接模式。
  • 考虑性能开销:在桥接模式中,抽象类和具体实现类之间的调用可能会引入性能开销,因此在性能关键的应用程序中要谨慎使用。
  • 使用清晰的命名约定:为抽象接口、扩展抽象和具体实现类使用明确的命名约定,以提高代码的可读性和可维护性。
6.总结


桥接模式通过将抽象部分和实现部分分离,使得两者可以独立变化,能够做到抽象接口只定义高级概念,而具体实现提供具体的实现细节

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

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

相关文章

从iconfont引入线上字体库

如果是长期使用建议直接下载字体包 /* 在线链接服务仅供平台体验和调试使用&#xff0c;平台不承诺服务的稳定性&#xff0c;企业客户需下载字体包自行发布使用并做好备份。 */ 例如使用阿里妈妈数黑体 https://www.iconfont.cn/fonts/detail?spma313x.fonts_index.i1.d9df…

手动加载PE文件

今天手撸一下加载PE文件&#xff0c;并执行加载的PE文件。看完这一节之后相信大家会对PE文件的结构和在内存中的加载顺序有一个比较深刻的理解。 本文中可能对PE文件的基础知识介绍的不是很详细&#xff0c;建议大家先看看PE文件的基础结构&#xff0c;了解了这些基础知识后再看…

数据库面试总结

数据库相关 mysql使用的函数 字符相关: concant() 连接字符 trim()去除字符的首尾空格 space(n) 返回n个空格 char_length() 返回字符的个数 ucase()/upper()将字符串 s 的所有字母变成大写字母 lcase()/lower() 将字符串 s 的所有字母变成小写字母 substr/substring/mid(s, …

第十五章 数据管理成熟度评估练习

单选题 (每题1分,共19道题) 1、 [单选] 下列选项中属于数据管理成熟度2级特征的选项是? A:很少或没有治理;有限的工具集;单个竖井(系统)内定义角色;控件(如果有的话的应用完全不一致);未解决的数据质量问题 B:治理开始出现;引入一致的工具集;定义了一些角色和…

杂记-记一次前端打包问题解决过程

背景 若干年没更新发布的前端项目&#xff0c;突然来了个小需求&#xff0c;需求完成耗时5min&#xff0c;打包问题解决2小时 问题 error commander12.0.0: The engine “node” is incompatible with this module. Expected version “>18”. Got “10.22.1” 这个错误…

卷积神经网络边缘识别

为什卷积神经网络能够识别图片呢&#xff1f;是基于图片相似度比较&#xff0c;两张图片的点击越大说明两张图片越像&#xff0c;比如我们那狗胡子的图片去比较&#xff0c;如果相似度很高&#xff0c;就是认为这个动物更像狗。点积越大&#xff0c;图片越相似&#xff0c;这个…

vivado Virtex UltraScale 配置存储器器件

Virtex UltraScale 配置存储器器件 下表所示闪存器件支持通过 Vivado 软件对 Virtex UltraScale ™ 器件执行擦除、空白检查、编程和验证等配置操作。 本附录中的表格所列赛灵思系列非易失性存储器将不断保持更新 &#xff0c; 并支持通过 Vivado 软件对其中所列非易失…

基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (六)

LlaMA 3 系列博客 基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (一) 基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (二) 基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (三) 基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (四) 基于 LlaMA…

第三课,python基础语法(二),基本算术运算符、3种数据类型、变量命名规则

一&#xff0c;基本算术运算 数学中&#xff1a;&#xff0c;-&#xff0c;&#xff0c; *小练习 请在程序中&#xff0c;定义如下变量&#xff1a; 钱包余额(变量名&#xff1a;money)&#xff0c;初始余额50 请通过程序计算&#xff0c;再购买了&#xff1a; 冰淇淋10元可…

微信小程序、uniapp密码小眼睛

直接上代码喔喔喔喔喔喔喔喔~~ <input name"username" password"{{passwordHideShow}}" placeholder-style"color:#bdbdbd" type"text"maxlength"20" value"{{passwordNumber}}" bindinput"passwordInput…

荷香堪筑梦,鸳鸯和月寻。(变相BFS搜索)

本题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例&#xff1a; 输入 3 4 2 .... ***. ..a. 输出 yes 思路&#xff1a; 根据题意&#xff0c;这里 1 s 可以移动多次&#xff0c;我们将每次可以移动避开雪的的位置存储起来&#xff0c;判断当…

randperm函数打乱索引的用法

randperm&#xff0c;用于生成一个随机排列。这个函数可以被用于许多需要随机排列的情况&#xff0c;如数据集的划分、模型的训练等等。通过randperm函数&#xff0c;你可以得到一个随机的、不重复的排列。 下面是randperm函数的一些用法示例&#xff1a; 1. 生成一个长度为n…

地埋式可燃气体监测终端,地下燃气管网安全“哨兵”

在现代都市的繁华之下&#xff0c;一条条地下燃气管网承载着城市的生命与活力&#xff0c;但管网老化腐蚀&#xff0c;第三方施工破坏&#xff0c;巡检维修不到位等问题&#xff0c;时刻影响着燃气管网安全运行&#xff0c;甚至威胁人民群众的生命财产安全。 为实现对燃气管网…

实现一个拆分实数的整数和小数部分的函数指针

#include <stdio.h> // 定义常量 #define LARGE_NUMBER 1000000000 // 定义一个常量&#xff0c;方便后续使用 void splitFloatIntoParts(float x, int *intpart, float *fracpart); // 声明一个分割浮点数为整数和小数部分的函数 int main() // 主函数开始 { …

轻松寄快递,推荐一款寄快递优惠的小程序!

不管我们经不经常寄快递&#xff0c;我们总是要处理寄快递收快递的事情&#xff0c;可是我们不想这么麻烦来处理寄快递的事情&#xff0c;怎么办呢&#xff1f;这里推荐大家使用闪侠惠递来寄快递&#xff0c;因为使用闪侠惠递寄快递&#xff0c;不仅是带给你便宜的寄快递价格&a…

linux进阶高级配置,你需要知道的有哪些(10)-远程访问

1、ssh协议的功能 为客户机提供安全的shell环境&#xff08;字符界面&#xff09;&#xff0c;用于远程管理 2、openssh的服务说明 服务名&#xff1a;sshd 重启服务&#xff1a;systemctl restart sshd 主配置文件&#xff1a;/etc/ssh/sshd/_config 端口号&#xff1a;tcp 2…

代码随想录第五十一天|最长递增子序列、最长连续递增序列、最长重复子数组

题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;

【数据库原理及应用】期末复习汇总高校期末真题试卷11

试卷 一、填空题(每题 1 分&#xff0c;共10 分)    1. 数据库管理技术的发展经历了三个阶段&#xff1a;人工管理阶段&#xff0c;文件系统阶段和__________阶段。 2.实体完整性约束规定__________的取值不能为空值。 3. 计算机系统有三类安全性问题&#xff0c;即_____…

企业使用合同档案管理系统软件有什么好处

使用合同档案管理系统软件可以带来以下好处&#xff1a; 1. 提高效率&#xff1a;合同管理软件可以自动化合同流程&#xff0c;包括创建、审批、签署和归档等。通过自动化&#xff0c;可以节省大量时间和精力&#xff0c;提高工作效率。 2. 降低风险&#xff1a;玖拓档案合同管…

重构四要素:目的、对象、时机和方法

目录 1.引言 2.重构的目的:为什么重构(why) 3.重构的对象:到底重构什么(what) 4.重构的时机:什么时候重构(when) 5.重构的方法:应该如何重构(how) 6.思考题 1.引言 一些软件工程师对为什么要重构(why)、到底重构什么(what)、什么时候重构(when)应该如何重构(how)等问题的…