【设计模式深度剖析】【5】【结构型】【桥接模式】| 以电视和遥控器为例加深理解

👈️上一篇:组合模式

设计模式-专栏👈️

目 录

  • 桥接模式(Bridge Pattern)
  • 定义
    • 英文原话是:
    • 直译
    • 理解
  • 4个角色
    • UML类图
    • 代码示例
  • 应用
    • 优点
    • 缺点
    • 使用场景
  • 示例解析:电视和遥控器
    • UML类图

桥接模式(Bridge Pattern)

定义

英文原话是:

  • Bridge Pattern is a software design pattern that is used to overcome the limitations of the traditional inheritance.
  • It decouples an abstraction from its implementation so that the two can vary independently.
  • The bridge pattern consists of two parts: abstraction and implementation.
  • The abstraction part defines the interface that the client uses to interact with the system.
  • The implementation part implements the abstraction by providing the functionality required by the client.

直译

  • 桥接模式是一种用于克服传统继承局限性的软件设计模式。
  • 它将抽象部分与实现部分解耦,使得两者可以独立地变化
  • 桥接模式由两部分组成:抽象部分和实现部分。
    • 抽象部分定义了客户端与系统交互的接口。
    • 实现部分通过提供客户端所需的功能来实现抽象部分。

理解

桥接模式(Bridge Pattern)从字面上理解,可以想象成一个桥梁连接了两个不同的部分,使得这两个部分可以相互通信或协作,而不需要彼此之间有直接的依赖关系。在软件设计中,这两个部分通常指的是抽象部分和实现部分。

在桥接模式中,抽象部分定义了一个接口(或抽象类),用于定义抽象层的行为。实现部分则实现了这个接口,提供了具体实现。这两个部分通过组合的方式关联在一起,而不是继承。这样做的好处是,抽象部分和实现部分可以独立变化,只要它们遵循相同的接口规范。

桥接模式的主要目的是通过组合的方式建立抽象与实现之间的联系,而不是通过继承。

这允许开发人员在不修改抽象接口的情况下修改实现,从而提高了系统的灵活性和可扩展性。

同时,桥接模式也避免了多重继承可能带来的问题,如违背类的单一职责原则和降低复用性等。

4个角色

桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与它的实现部分分离,使得它们可以独立地变化。这种类型的设计模式属于结构型模式,它通过提供抽象层和实现层之间的桥接结构,来实现二者的解耦。

UML类图

在这里插入图片描述

桥接模式包含以下四个角色:

  1. 抽象化(Abstraction)角色:定义抽象类的接口,并保存一个对实现化对象的引用。
  2. 扩展抽象化(RefinedAbstraction)角色:抽象化角色的子类,实现它要求的业务逻辑,并通过组合关系调用实现化角色中的业务方法。
  3. 实现化(Implementor)角色:这个接口定义了实现化角色的接口,但不提供具体的实现。这个接口必须被实现化角色的具体类来实现。
  4. 具体实现化(ConcreteImplementor)角色:实现化角色接口的具体实现类。

代码示例

以下是一个Java示例来演示桥接模式:

package com.polaris.designpattern.list2.structural.pattern5.bridge.classicdemo;// 实现化角色接口
interface Implementor {  void operationImpl();  
}  // 具体实现化角色  
class ConcreteImplementorA implements Implementor {  @Override  public void operationImpl() {  System.out.println("操作A的实现");  }  
}  class ConcreteImplementorB implements Implementor {  @Override  public void operationImpl() {  System.out.println("操作B的实现");  }  
}  // 抽象化角色  
abstract class Abstraction {  protected Implementor implementor;  public Abstraction(Implementor implementor) {  this.implementor = implementor;  }  public abstract void operation();  
}  // 扩展抽象化角色  
class RefinedAbstraction extends Abstraction {  public RefinedAbstraction(Implementor implementor) {  super(implementor);  }  @Override  public void operation() {  // 在调用实现化角色的方法之前或之后,可以添加一些逻辑  System.out.println("扩展操作前...");  implementor.operationImpl();  System.out.println("扩展操作后...");  }  
}  // 客户端代码  
public class BridgePatternDemo {  public static void main(String[] args) {  Implementor implementorA = new ConcreteImplementorA();  Abstraction abstraction = new RefinedAbstraction(implementorA);  abstraction.operation();System.out.println("-----------");Implementor implementorB = new ConcreteImplementorB();  abstraction = new RefinedAbstraction(implementorB);  abstraction.operation();  }  
}/* Output:
扩展操作前...
操作A的实现
扩展操作后...
-----------
扩展操作前...
操作B的实现
扩展操作后...
*///~

在这个例子中,Implementor 是实现化角色接口,ConcreteImplementorAConcreteImplementorB 是两个具体实现化角色。Abstraction 是抽象化角色,它持有一个对实现化角色的引用,而 RefinedAbstraction 是扩展抽象化角色,它扩展了 Abstraction 的功能。客户端代码通过组合关系,将实现化角色和抽象化角色组合在一起,实现了二者的解耦。

应用

再来总结下,桥接模式(Bridge Pattern)是一种结构型设计模式,它通过将抽象部分与实现部分解耦,使得它们可以独立地变化。

桥接模式通常用于以下情况:

  1. 抽象和实现需要独立变化:当抽象部分和实现部分都需要独立扩展时,可以使用桥接模式。例如,不同的数据库系统(抽象部分)可能需要不同的驱动程序(实现部分)。
  2. 需要跨多个平台实现:当系统需要在不同的平台上运行时,可以使用桥接模式来封装平台相关的代码。
  3. 避免继承层次过深:当使用继承来实现多个维度的变化时,可能会导致继承层次过深,使得代码难以理解和维护。桥接模式通过组合代替继承,可以解决这个问题。

优点

  1. 分离抽象与实现:桥接模式将抽象部分与实现部分分离,使得它们可以独立地变化。这增加了系统的灵活性和可扩展性。
  2. 减少继承层次:通过组合关系替代继承关系,减少了继承层次,降低了系统的复杂度。
  3. 支持动态切换实现:在运行时,可以动态地切换实现部分,而不需要修改抽象部分的代码。
  4. 符合开闭原则:桥接模式符合开闭原则,即对扩展开放,对修改封闭。当需要添加新的实现时,只需要添加新的实现类,而不需要修改已有的代码。

缺点

  1. 增加了系统的复杂性:由于引入了抽象部分和实现部分两个层次,增加了系统的复杂性。对于简单的系统来说,可能不需要使用桥接模式。
  2. 可能增加了系统开销:在运行时,需要维护抽象部分和实现部分之间的关联关系,这可能会增加一些额外的开销。

使用场景

以下是一些适合使用桥接模式的场景:

  1. 多种操作系统:当软件需要在多种操作系统上运行时,可以使用桥接模式来封装与操作系统相关的代码。这样,只需要编写一次抽象部分的代码,就可以通过更换不同的实现部分来适应不同的操作系统。
  2. 多种数据库系统:当软件需要与多种数据库系统进行交互时,可以使用桥接模式来封装与数据库相关的代码。这样,只需要编写一次抽象部分的代码,就可以通过更换不同的实现部分来适应不同的数据库系统。
  3. 多种图形用户界面:当软件需要支持多种图形用户界面(如Windows、Mac、Linux等)时,可以使用桥接模式来封装与界面相关的代码。这样,只需要编写一次抽象部分的代码,就可以通过更换不同的实现部分来适应不同的界面风格。
  4. 多种网络协议:当软件需要与多种网络协议进行通信时,可以使用桥接模式来封装与网络协议相关的代码。这样,只需要编写一次抽象部分的代码,就可以通过更换不同的实现部分来适应不同的网络协议。

示例解析:电视和遥控器

在生活中,一个常见的桥接模式的例子是电视和遥控器。

电视(抽象化角色)提供了观看节目的基本功能,而遥控器(实现化角色)则负责控制电视的不同操作(如换台、调节音量等)。

电视本身不关心遥控器是如何实现的,只要它符合一定的接口规范(如红外信号、蓝牙等)。

同样,遥控器也可以控制不同类型的电视,只要电视也符合相应的接口规范。

UML类图

在这里插入图片描述

下面是一个简化的代码示例,用于说明这个场景:

package com.polaris.designpattern.list2.structural.pattern5.bridge.remotecontroldemo;//遥控器接口(Implementor)
interface RemoteControl {//换台void changeChannel(int channel);//调节音量void adjustVolume(int volume);// ... 其他控制方法  
}//具体遥控器(ConcreteImplementor)  
class InfraredRemoteControl implements RemoteControl {@Overridepublic void changeChannel(int channel) {System.out.println("使用红外遥控器换台到: " + channel);}@Overridepublic void adjustVolume(int volume) {System.out.println("使用红外遥控器调节音量到: " + volume);}// ... 实现其他控制方法  
}//电视抽象类(Abstraction) 
abstract class Television {protected RemoteControl remoteControl;public Television(RemoteControl remoteControl) {this.remoteControl = remoteControl;}public abstract void turnOn();public abstract void turnOff();// 使用遥控器来控制电视  public void watch() {System.out.println("正在看电视...");remoteControl.changeChannel(10); // 假设切换到10频道  remoteControl.adjustVolume(50); // 假设调节音量到50  }
}//具体电视类(RefinedAbstraction) 
class LEDTelevision extends Television {public LEDTelevision(RemoteControl remoteControl) {super(remoteControl);}@Overridepublic void turnOn() {System.out.println("LED电视已打开");}@Overridepublic void turnOff() {System.out.println("LED电视已关闭");}
}//客户端代码  
public class BridgePatternDemo {public static void main(String[] args) {// 创建一个红外遥控器  RemoteControl infraredRemote = new InfraredRemoteControl();// 创建一个LED电视,并使用红外遥控器  Television ledTv = new LEDTelevision(infraredRemote);ledTv.turnOn(); // 打开电视  ledTv.watch(); // 使用遥控器观看电视  ledTv.turnOff(); // 关闭电视  }
}/* Output:
LED电视已打开
正在看电视...
使用红外遥控器换台到: 10
使用红外遥控器调节音量到: 50
LED电视已关闭
*///~

在这个例子中,Television 是抽象化角色,它定义了电视的基本操作(如打开、关闭),并持有对 RemoteControl(遥控器)的引用。LEDTelevision 是扩展抽象化角色,它扩展了电视的基本功能,并提供了具体的实现。RemoteControl 是实现化角色接口,定义了遥控器需要实现的方法。InfraredRemoteControl 是具体实现化角色,它实现了红外遥控器的功能。

客户端代码创建了一个 InfraredRemoteControl 对象和一个 LEDTelevision 对象,并将遥控器对象传递给电视对象。这样,电视就可以通过遥控器来控制自己的行为了。

这个例子展示了桥接模式如何使得抽象化角色(电视)和实现化角色(遥控器)可以独立地变化。


上一篇:组合模式👈️

设计模式-专栏👈️

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

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

相关文章

CC工具箱使用指南:【淹没区分析(BHM)】

一、简介 群友定制工具。 这个工具适用面比较小。 工具的应用场景如下: 提供一个淹没区范围,类型是面要素。统计这个范围内的一些线、面要素的面积或长度。 给定的几个数据有:耕地、永久基本农田、房台、道路(线)…

基于Docker搭建属于你的CC++集成编译环境

常常,我会幻想着拥有一个随时可以携带、随时可以使用的开发环境,那该是多么美好的事情。 在工作中,编译环境的复杂性常常让我头疼不已。稍有不慎,删除了一些关键文件,整个编译链就会瞬间崩溃。更糟糕的是,…

如何保养和维护气膜体育馆—轻空间

随着经济的飞速发展,气膜体育馆以其新颖的外观、优美的造型、节能环保的特点,迅速进入体育市场。然而,对于气膜体育馆的维护和保养是不容忽视的问题,必须引起重视。下面我们将详细介绍气膜体育馆的维护需要从哪些方面着手。 一、保…

【电路笔记】-状态可变滤波器

状态可变滤波器 文章目录 状态可变滤波器1、概述2、**状态可变滤波器电路**3、状态可变滤波器示例4、陷波滤波器设计5、总结状态可变滤波器是一种多反馈滤波器电路,可以从同一单个有源滤波器设计中同时产生所有三种滤波器响应:低通、高通和带通。 1、概述 状态可变滤波器使用…

基于Java+SpringBoot+Mybaties-plus+Vue+elememt + uniapp 新闻资讯 的设计与实现

一.项目介绍 本系统分为 后端 和 小程序端 后端:点击登录按钮 设置个人中心、 管理员账号数据维护、 基础数据维护、 短视频信息维护(包括查看短视频留言、短视频收藏)、 论坛维护(增删改查帖子信息,包括查…

Rabbit MQ学习之《基础概念》

Message Queue 1 什么是MQ MQ(message queue),本质是个队列,FIFO 先入先出,只不过队列中存放的内容是message而已,同时是一种跨进程的通信机制,用于上下游传递消息。 在互联网架构中,MQ 是一种非常常见的…

钡铼技术BL205模块在智能制造产线的灵活配置与优化

钡铼技术的OPC UA耦合器BL205模块在智能制造产线中的灵活配置与优化是当今工业领域中的一个关键议题。随着工业4.0和数字化转型的不断推进,生产线的灵活性和智能化程度成为了企业追求的目标。在这一背景下,BL205模块以其分布式、可插拔、结构紧凑、可编程…

Pytorch中的torch.save()文件保存格式探索以及mmdetection加载预训练模型参数对不齐和收到意外参数报错解决方案

使用mmdetection时遇到的问题比较多,首先要对自己要使用的预训练模型有一定的了解,并且懂得使用各种分类模型时不同的模型不同任务执行阶段需要参数上的对其。(比如mask-rcnn和它的三个头之间的参数)。 首先,谈谈torc…

Spring Boot集成六大常用中间件,附集成源码,亲测有效

目录 万字论文,从0到1,只需1小时获取途径1、Spring Boot如何集成Spring Data JPA?2、Spring Boot如何集成Spring Security?3、Spring Boot如何集成Redis?4、Spring Boot如何集成RabbitMQ?5、Spring Boot如何…

11 Goroutine-并发与并行、阻塞与非阻塞

并发 顺序执行:按照事先计划好的顺序,执行完一个操作后,再执行下一个操作。 顺序执行效率不高的原因: 每个操作由多个步骤组成,每个步骤所需要的时间长短不一,有些步骤可能相当耗时。顾客点菜需要时间&a…

VectorDBBench在windows的调试

VectorDBBench在windows的调试 VectorDBBench是一款向量数据库基准测试工具,支持milvus、Zilliz Cloud、Elastic Search、Qdrant Cloud、Weaviate Cloud 、 PgVector、PgVectorRS等,可以测试其QPS、时延、recall。 VectorDBBench是一款使用python编写的…

深度学习模型在OCR中的可解释性问题与提升探讨

摘要: 随着深度学习技术在光学字符识别(OCR)领域的广泛应用,人们对深度学习模型的可解释性问题日益关注。本文将探讨OCR中深度学习模型的可解释性概念及其作用,以及如何提高可解释性,使其在实际应用中更可…

Java 零基础入门学习(小白也能看懂!)

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…

第16篇:JTAG UART IP应用<三>

Q:如何通过HAL API函数库访问JTAG UART? A:Quartus硬件工程以及Platform Designer系统也和第一个Nios II工程--Hello_World的Quartus硬件工程一样。 Nios II软件工程对应的C程序调用HAL API函数,如open用于打开和创建文件&#…

使用YOLOv9训练和测试自己的数据集

任务:检测舌头上的裂纹和齿痕 已经有了labelme标注的数据集,并且转为了coco格式 参考: 详细!正确!COCO数据集(.json)训练格式转换成YOLO格式(.txt)_coco数据集的train…

服务器数据恢复—服务器raid常见故障表现原因解决方案

RAID(磁盘阵列)是一种将多块物理硬盘整合成一个虚拟存储的技术,raid模块相当于一个存储管理的中间层,上层接收并执行操作系统及文件系统的数据读写指令,下层管理数据在各个物理硬盘上的存储及读写。相对于单独的物理硬…

2023年全国青少年人工智能创新挑战赛真题

为了大家备考2024年第七届全国青少年人工智能创新挑战赛,今天分享2023年第6届全国青少年人工智能创新挑战赛C信息学专项真题,图形化编程及Python编程基本大同小异,参考6547网的Python及图形化编程题库。 一、单项选择题(共 15 题,每题 2 分,共…

vscode中使用conda虚拟环境

每一次配置环境,真的巨烦,网上的资料一堆还得一个个尝试,遂进行整理 1.准备安装好Anaconda 附带一篇测试教程,安装anaconda 2.准备安装vscode 安装地址:Visual Studio Code 3.创建Conda环境 搜索框搜索Anaconda…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《计及液态空气储能与综合需求响应的综合能源系统低碳经济调度》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

HTML静态网页成品作业(HTML+CSS)——游戏阴阳师介绍网页(4个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有4个页面。 二、作品演示 三、代…