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

设计模式笔记_结构型_桥接模式

1.桥接模式介绍

1.1 定义

桥接模式是一种结构型设计模式,它的主要目的是将抽象部分实现部分分离,通过组合的方式实现二者解耦,使它们可以独立地变化。

其中:

  • 抽象部分:描述“是什么”和“做什么”。通常是指对事物的高层次描述,它定义了事物的核心功能和行为,而不关心具体的实现细节。抽象通常比较稳定,因为它描述的是核心功能。
  • 实现部分:描述“怎么做”。是抽象部分定义功能的具体执行者,它提供了具体的代码来完成抽象所定义的行为。实现可能经常变化,因为它涉及具体的技术和业务逻辑。

1.2 举例说明

这里以“遥控器和电视机”的例子来说明桥接模式的功能。


1.2.1 没有“桥接模式”之前:

我们可能会这样做:

  • 你买了一台索尼电视,它配了一个索尼普通遥控器
  • 后来你又买了一台三星电视,它配了一个三星普通遥控器

但问题来了:你觉得普通遥控器功能太少,想换个“智能遥控器”(比如带语音控制的)。这时你会发现:

  • 你需要一个 “索尼智能遥控器” 去控制索尼电视。
  • 你需要一个 “三星智能遥控器” 去控制三星电视。
  • 如果将来又出了个“小米电视”,你又需要一个 “小米智能遥控器”

你看,遥控器的“类型”(普通、智能)和电视机的“品牌”(索尼、三星、小米)被死死地绑在了一起。每增加一个遥控器类型,或者每增加一个电视品牌,你就得新增一大堆对应的遥控器。这就叫 “类爆炸”,非常不灵活。


1.2.2 有桥接模式:万能遥控器

桥接模式就像是发明了 “万能遥控器”。它的思路是这样的:

“遥控器的功能” 和 “电视机具体怎么执行这个功能” 是两件独立的事情,我们应该把它们分开!

于是,我们有了两个独立的东西:

  1. 抽象部分(Abstractions):遥控器

    • 它只管定义“有什么功能”,比如:开机、关机、换台。
    • 它可以有不同的类型,比如:
      • 普通遥控器 (只有基本功能)
      • 智能遥控器 (在基本功能上,增加了语音控制)
  2. 实现部分(Implementations):电视机

    • 它只管“具体怎么干活”
    • 不同品牌的电视机,执行同一个命令的方式可能完全不同(比如它们的红外码不一样)。
      • 索尼电视 的开机方法。
      • 三星电视 的开机方法。
      • 小米电视 的开机方法。

那么,“桥”在哪里呢?

这个“桥”就是把遥控器和电视机连接起来的机制。在万能遥控器内部,有一个“插槽”,你可以把具体的“电视机驱动”(也就是实现部分)插进去。

  • 当你的智能遥控器想控制索尼电视时,它就把“索尼电视的驱动”加载进来。你按“开机”按钮,遥控器就会调用索尼电视的开机方法。
  • 明天你想用这个智能遥控器去控制三星电视,没问题,把驱动换成“三星电视的驱动”就行了。你再按“开机”,遥控器就会去调用三星电视的开机方法。

1.2.3 桥接模式的好处

通过这座“桥”,我们成功地将两个原本纠缠在一起的维度分开了:

  • 维度一:遥控器的功能层级 (普通遥控器 -> 智能遥控器 -> 未来可能的全息遥控器)
  • 维度二:电视机的具体品牌 (索尼 -> 三星 -> 小米 -> 华为)

这两个维度现在可以独立发展,互不影响

  • 你想升级遥控器?没问题,买个新的智能遥控器就行,它照样能控制你家的所有旧电视。
  • 你想换个新电视?也没问题,你手里的旧遥控器,只要配对一下,照样能控制新电视。

用一句话概括:桥接模式就像一座桥,将“做什么”(抽象)和“怎么做”(实现)分置于河的两岸,让它们可以各自独立地变化和发展,但又通过这座桥保持连接。

它的核心思想就是 “解耦” (Decoupling),避免因为一个维度的变化,导致另一个维度也要跟着做大量的修改。

2. 代码演示

2.1 桥接模式演示

2.1.1 实现部分:电视机

//实现部分接口
public interface TV {void on();void off();void tuneChannel(int channel);
}//具体的实现部分
//索尼品牌的电视
public class SonyTV implements TV {@Overridepublic void on() {System.out.println("Sony TV is turned on.");}@Overridepublic void off() {System.out.println("Sony TV is turned off.");}@Overridepublic void tuneChannel(int channel) {System.out.println("Sony TV tuned to channel " + channel);}
}//三星品牌的电视
public class SamsungTV implements TV {@Overridepublic void on() {System.out.println("Samsung TV is turned on.");}@Overridepublic void off() {System.out.println("Samsung TV is turned off.");}@Overridepublic void tuneChannel(int channel) {System.out.println("Samsung TV tuned to channel " + channel);}
}

2.2.2 抽象部分:遥控器

//抽象部分
public abstract class RemoteControl {protected TV tv;public RemoteControl(TV tv) {this.tv = tv;}public abstract void turnOn();public abstract void turnOff();public abstract void setChannel(int channel);}//具体抽象部分
public class BasicRemoteControl extends RemoteControl {public BasicRemoteControl(TV tv) {super(tv);}@Overridepublic void turnOn() {tv.on();}@Overridepublic void turnOff() {tv.off();}@Overridepublic void setChannel(int channel) {tv.tuneChannel(channel);}
}

2.2.3 使用Demo

使用遥控器控制各种品牌电视机:

public class BridgePatternDemo {public static void main(String[] args) {TV sonyTV = new SonyTV();RemoteControl sonyRemote = new BasicRemoteControl(sonyTV);sonyRemote.turnOn();sonyRemote.setChannel(5);sonyRemote.turnOff();TV samsungTV = new SamsungTV();RemoteControl samsungRemote = new BasicRemoteControl(samsungTV);samsungRemote.turnOn();samsungRemote.setChannel(10);samsungRemote.turnOff();}
}

2.2 桥接模式应对变化

2.2.1 实现部分:变化

市场又出了一款小米电视机,电视机(实现部分)的品牌变化,不影响遥控器(抽象部分)的使用。

//新出现一款小米品牌的电视
public class XiaomiTV implements TV {@Overridepublic void on() {System.out.println("Xiaomi TV is turned on.");}@Overridepublic void off() {System.out.println("Xiaomi TV is turned off.");}@Overridepublic void tuneChannel(int channel) {System.out.println("Xiaomi TV tuned to channel " + channel);}
}

使用遥控器控制小米电视:

public class BridgePatternDemo {public static void main(String[] args) {TV sonyTV = new SonyTV();RemoteControl sonyRemote = new BasicRemoteControl(sonyTV);sonyRemote.turnOn();sonyRemote.setChannel(5);sonyRemote.turnOff();TV samsungTV = new SamsungTV();RemoteControl samsungRemote = new BasicRemoteControl(samsungTV);samsungRemote.turnOn();samsungRemote.setChannel(10);samsungRemote.turnOff();//新增对小米电视的控制TV xiaomiTV = new XiaomiTV();RemoteControl samsungRemote = new BasicRemoteControl(xiaomiTV);samsungRemote.turnOn();samsungRemote.setChannel(10);samsungRemote.turnOff();}
}

2.2.2 抽象部分:变化

普通遥控器已经满足不了需求,需要一款能语音控制的智能遥控器。遥控器(抽象部分)的演进,不影响电视机(实现部分)的使用。

//新的抽象部分:智能遥控器 (在基本功能上,增加了语音控制)
public abstract class AdvancedRemoteControl extends RemoteControl {public AdvancedRemoteControl(TV tv) {super(tv);}public abstract void turnOnByVoice();public abstract void turnOffByVoice();public abstract void setChannelByVoice(int channel);
}//具体新的抽象部分:智能遥控器
public class SmartRemoteControl extends AdvancedRemoteControl {public SmartRemoteControl(TV tv) {super(tv);}@Overridepublic void turnOn() {tv.on();}@Overridepublic void turnOff() {tv.off();}@Overridepublic void setChannel(int channel) {tv.tuneChannel(channel);}@Overridepublic void turnOnByVoice() {tv.on();}@Overridepublic void turnOffByVoice() {tv.off();}@Overridepublic void setChannelByVoice(int channel) {tv.tuneChannel(channel);}
}

使用智能遥控器控制三星电视机:

public class BridgePatternDemo {public static void main(String[] args) {TV sonyTV = new SonyTV();RemoteControl sonyRemote = new BasicRemoteControl(sonyTV);sonyRemote.turnOn();sonyRemote.setChannel(5);sonyRemote.turnOff();TV samsungTV = new SamsungTV();RemoteControl samsungRemote = new BasicRemoteControl(samsungTV);samsungRemote.turnOn();samsungRemote.setChannel(10);samsungRemote.turnOff();// 使用智能遥控器AdvancedRemoteControl smartRemote = new SmartRemoteControl(samsungTV);smartRemote.turnOn();smartRemote.setChannel(10);smartRemote.turnOff();smartRemote.turnOnByVoice();smartRemote.setChannelByVoice(20);smartRemote.turnOffByVoice();}
}

2.3 总结

在上述例子中,TV接口和它的实现类代表了实现部分,而RemoteControl抽象类和它的具体实现类代表了抽象部分

通过这种分离,抽象定义了系统的功能接口,而实现则负责具体的操作细节。因此,它们可以独立变化:新的电视品牌可以通过实现TV接口添加,而遥控器的新功能可以通过扩展RemoteControl类来实现,而不会相互影响。

http://www.lryc.cn/news/587489.html

相关文章:

  • vscode 安装 esp ide环境
  • 基于MATLAB的LSTM长短期记忆神经网络的数据回归预测方法应用
  • 02 51单片机之LED闪烁
  • 前端同学,你能不能别再往后端传一个巨大的JSON了?
  • 构建完整工具链:GCC/G++ + Makefile + Git 自动化开发流程
  • 前端接入海康威视摄像头的三种方案
  • autoware激光雷达和相机标定
  • JAVA 设计模式 工厂
  • Docker搭建Redis分片集群
  • 鸿蒙应用开发: 鸿蒙项目中使用私有 npm 插件的完整流程
  • Kotlin集合接口
  • 常用的OTP语音芯片有哪些?
  • 前端性能与可靠性工程系列: 渲染、缓存与关键路径优化
  • Spring Boot - Spring Boot 集成 MyBatis 分页实现 PageHelper
  • 【React Native】环境变量和封装 fetch
  • 智源:LLM指令数据建设框架
  • VR样板间:房产营销新变革
  • Cesium 9 ,Cesium 离线地图本地实现与服务器部署( Vue + Cesium 多项目共享离线地图切片部署实践 )
  • 谷歌开源库gtest 框架安装与使用
  • VR全景制作流程?什么是全景?
  • ELK、Loki、Kafka 三种日志告警联动方案全解析(附实战 Demo)
  • EVOLVEpro安装使用教程-蛋白质语言模型驱动的快速定向进化
  • 快速搭建Maven仓库服务
  • 前端面试十二之vue3基础
  • 从代码学习深度强化学习 - DDPG PyTorch版
  • CCPD 车牌数据集提取标注,并转为标准 YOLO 格式
  • MySQL 分表功能应用场景实现全方位详解与示例
  • JavaSE-多态
  • 010_学习资源与社区支持
  • Linux713 SAMBA;磁盘管理:手动挂载,开机自动挂载,自动挂载