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

动手实现第一个桥接:从接口到具体类

简单说,桥接模式就是:把“做什么”和“怎么做”彻底分开,让它们各自独立变化。


先来一个生活类比:遥控器和电视机

想象一下,你坐在沙发上,手里拿着一个万能遥控器。这个遥控器上只有三个按钮:开机、调音量、换频道。你根本不需要知道电视机里面是液晶屏还是老式显像管,也不关心它是索尼还是创维。你只要按按钮,电视就执行对应的动作。

现在问题来了:如果有一天,你家换了一台投影仪,遥控器还能用吗?如果遥控器本身从红外线升级成了蓝牙,电视机需要跟着换吗?

答案是:都不需要。因为遥控器只关心“按什么键”,电视机只关心“执行什么动作”。它们之间通过一个通用的“接口”(比如红外信号协议)沟通,彼此完全独立。

这就是桥接模式的核心思想:把抽象(遥控器上的按钮)和实现(电视机怎么响应)拆成两条独立的轨道,中间用一座桥连接起来。


为什么会有这个发明?——一个程序员的血泪故事

让我们回到一个真实的开发场景。

假设你接到了一个任务:为一个画图软件实现“形状”功能。老板说:“先支持圆形和方形,颜色嘛,先支持红色和蓝色。”

你一拍脑袋,很快就写出来了:

  • 一个RedCircle(红圆)类
  • 一个BlueCircle(蓝圆)类
  • 一个RedSquare(红方)类
  • 一个BlueSquare(蓝方)类

看起来没问题,对吧?但老板第二天说:“再加一个绿色。” 你就要新增两个类:GreenCircleGreenSquare。第三天老板又说:“再加一个三角形。” 你又要新增三个类:RedTriangleBlueTriangleGreenTriangle

你发现规律了吗?如果有 M 种形状,N 种颜色,你就要写 M × N 个类。这个数字会像野草一样疯长。更可怕的是,每次新增一种颜色或者一种形状,你都要修改已有的代码——这就像每次换灯泡都要重新装修整个房子。

这就是“类爆炸”问题。根本原因在于:你把“形状是什么”和“颜色怎么画”这两个本该独立变化的东西,强行绑在了一起。


桥接模式怎么解决?——拆成两条轨道

桥接模式的做法很简单:把形状和颜色拆成两个独立的“维度”

  • 维度一(抽象层):形状 —— 只关心“我是什么形状”,不关心“怎么画颜色”
  • 维度二(实现层):颜色 —— 只关心“怎么画颜色”,不关心“画在什么形状上”

然后,用一座“桥”把它们连接起来:每个形状对象里,持有一个颜色对象的引用。

第一步:定义颜色接口(实现层)

先定义“颜色”这个维度。它只负责一件事:告诉别人怎么填充颜色

// 颜色接口 —— 只关心“怎么画颜色” interface Color { void applyColor(); // 应用颜色 }

这个接口就像遥控器上的“红外信号协议”。它只规定了“你要能发送信号”,但不管信号是控制电视还是空调。

第二步:实现具体颜色

现在我们可以随意添加具体颜色,每个颜色只需要实现applyColor()方法。

// 红色实现 class RedColor implements Color { public void applyColor() { System.out.println("应用红色"); } } // 蓝色实现 class BlueColor implements Color { public void applyColor() { System.out.println("应用蓝色"); } }

注意:这里没有任何形状的影子。颜色类完全不知道自己是画在圆形上还是方形上。它只负责“把红色涂上去”。

第三步:定义形状抽象(抽象层)

现在定义“形状”这个维度。它不直接画颜色,而是委托给颜色对象去做。

// 形状抽象 —— 只关心“我是什么形状”,但需要颜色帮忙 abstract class Shape { protected Color color; // 桥!形状里持有颜色的引用 // 构造函数:把颜色“注入”进来 public Shape(Color color) { this.color = color; } abstract void draw(); // 画形状,但具体怎么画颜色?交给 color 去做 }

这里的Color color就是那座。形状类不自己实现颜色,而是通过这座桥,把“画颜色”的任务委托给传入的颜色对象。

第四步:实现具体形状

具体形状只需要实现draw()方法,并在里面调用color.applyColor()

// 圆形 class Circle extends Shape { public Circle(Color color) { super(color); // 通过桥传入颜色 } public void draw() { System.out.print("画圆形,然后"); color.applyColor(); // 委托给颜色对象 } } // 方形 class Square extends Shape { public Square(Color color) { super(color); } public void draw() { System.out.print("画方形,然后"); color.applyColor(); } }

第五步:组装使用

现在,创建对象的方式变成了“组合式”的:

// 创建一个红色圆形 Shape redCircle = new Circle(new RedColor()); redCircle.draw(); // 输出:画圆形,然后应用红色 // 创建一个蓝色方形 Shape blueSquare = new Square(new BlueColor()); blueSquare.draw(); // 输出:画方形,然后应用蓝色

关键变化:当你需要新增一种颜色(比如绿色)时,你只需要写一个GreenColor类,所有形状自动就能用绿色。当你需要新增一种形状(比如三角形)时,你只需要写一个Triangle类,所有颜色自动就能用在这个形状上。

类数量从 M × N 变成了 M + N。这才是真正的“解耦”(分开独立)。


为什么叫“桥接”?

想象一下,形状和颜色原本是两座孤岛。桥接模式就是在它们之间建了一座桥:形状对象里持有颜色对象的引用。这座桥让它们可以通信,但彼此又不需要知道对方的内部细节。

  • 形状说:“我要画了,颜色你负责上色。”
  • 颜色说:“好的,我只管上色,不管画什么形状。”

这就是桥接的核心:用组合(持有引用)代替继承(父子关系),让两个维度可以独立变化。


真实世界的场景:图形编辑器

假设你正在开发一个图形编辑器,用户可以选择形状(圆形、方形、三角形)和颜色(红、蓝、绿、渐变)。如果没有桥接模式,每增加一种颜色,你就要为每种形状都写一个新类。很快,代码就会变成一团乱麻。

有了桥接模式:

  1. 形状团队只需要关注“怎么画形状的轮廓”,完全不用管颜色。
  2. 颜色团队只需要关注“怎么填充颜色”,完全不用管形状。
  3. 两个团队可以并行工作,各自添加新功能,互不干扰。

更妙的是,如果未来要支持“纹理”(比如木纹、大理石纹),你只需要新增一个“纹理”维度,再建一座桥连接到形状上。系统可以无限扩展,而不会爆炸。


小结:桥接模式的三个关键点

  1. 拆成两个维度:把“抽象”(形状)和“实现”(颜色)彻底分开。
  2. 用桥连接:抽象层持有实现层的引用,通过委托完成工作。
  3. 独立变化:任何一方新增变体,都不需要修改另一方。

最后留一个思考:桥接模式和“策略模式”很像,但有一个核心区别——策略模式是“换算法”,桥接模式是“拆维度”。你能感觉到它们的区别吗?

推荐一个学习网站,http://easelearningai.com 输入学习主题,会根据你的知识背景,帮你把学习内容讲得通俗易懂。

http://www.cnnetsun.cn/news/2886673.html

相关文章:

  • 从热阻计算到散热器选型:PowerPC 604处理器热管理实战解析
  • 西门子CFC 8.2.2离线安装包(含SFC 8.2.0兼容组件与多语言授权文件)
  • 别让FUA和Flush Cache搞晕你:OCP NVMe SSD掉电保护下的IO命令实战解析
  • 华硕笔记本终极控制神器:G-Helper全面使用指南
  • 别再傻傻重启了!USB PD协议里的Soft Reset、Hard Reset和Cable Reset到底啥区别?
  • Bulk Trace FEM在剪切刚性结构分析中的创新应用
  • 从玩具车到真汽车:聊聊EEPROM磨损均衡算法在Arduino和STM32上的开源实现
  • CE318太阳光度计本地化数据处理工具:一键完成AOD与大气水汽反演
  • 基于源代码嵌入的编程技能建模与个性化推荐系统
  • Halcon均值滤波mean_image实操:为什么你的图片一平滑就变‘糊’?
  • 机器学习模型生产部署:从Notebook到高可用API服务
  • 智慧树自动刷课插件:3分钟实现高效在线学习的终极解决方案
  • 别再傻傻分不清!用Python和C语言代码实例,彻底搞懂算术、逻辑、循环移位的区别
  • 给程序员的硬件课:拆解磁盘寻道与RAID0,你的数据库慢可能和它有关
  • 英雄联盟智能辅助工具完全指南:5大功能彻底改变你的游戏体验
  • 分析:ICEF认知框架的“强侵染性”特征及其与常规思维病毒的本质区别
  • 鼎阳示波器选件机制解析:从软件密钥生成到硬件功能验证,我们聊点干货
  • 回归模型评估指标实战指南:从MAE、RMSE到业务穿透率
  • PCA实战指南:从数据冗余诊断到业务可解释降维
  • 别再只盯着Accuracy了!用sklearn的classification_report看懂你的模型到底行不行
  • 探索SkyWater PDK:开源芯片设计的工艺设计套件深度解析
  • 10个业务驱动的Python实战项目:从语法到工作流
  • Agent 开发:你真的需要框架吗?
  • 从RTL到流片:CEVA BX2软核DSP的完整SoC集成避坑指南与工具链实战
  • 5G基带开发者的新选择:CEVA-BX2 DSP软核IP实战入门与工具链全解析
  • GPT-4稀疏激活原理:2%有效参数如何驱动万亿模型
  • 你的PBR材质为什么假?可能是辐照度图采样和粗糙度菲涅耳没搞对
  • CMake 015:日志级别全解析
  • 从二极管到MOS管:功率器件内部寄生电容的‘前世今生’与选型避坑指南
  • 创新高效的百度网盘提取码智能获取工具完整指南