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

news2024/10/6 4:07:19

👈️上一篇:组合模式    |   下一篇:外观模式👉️

设计模式-专栏👈️

目 录

  • 桥接模式(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 {
    @Override
    public void changeChannel(int channel) {
        System.out.println("使用红外遥控器换台到: " + channel);
    }

    @Override
    public 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);
    }

    @Override
    public void turnOn() {
        System.out.println("LED电视已打开");
    }

    @Override
    public 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.coloradmin.cn/o/1717286.html

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

相关文章

【漏洞复现】DT-高清车牌识别摄像机 任意文件读取漏洞

0x01 产品简介 DT-高清 车牌识别摄像机是一款先进的安防设备&#xff0c;采用高清图像传感器和先进的识别算法&#xff0c;能够精准、快速地识别车牌信息。其高清晰该摄像机结合了智能识别技术&#xff0c;支持实时监宴图像质量确保在各种光照和天气条件下都能准确捕捉车牌信息…

【设计模式】JAVA Design Patterns——Factory Method(虚拟构造器模式)

&#x1f50d;目的 为创建一个对象定义一个接口&#xff0c;但是让子类决定实例化哪个类。工厂方法允许类将实例化延迟到子类 &#x1f50d;解释 真实世界例子 铁匠生产武器。精灵需要精灵武器&#xff0c;而兽人需要兽人武器。根据客户来召唤正确类型的铁匠。 通俗描述 它为类…

视频汇聚管理平台EasyCVR程序报错“create jwtSecret del server class:0xf98b6040”的原因排查与解决

国标GB28181协议EasyCVR安防视频监控平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力&#xff0c;平台支持7*24小时实时高清视频监控&#xff0c;能同时播放多路监控视频流…

【学习笔记】Windows GDI绘图(八)画笔Pen与画刷Brush

文章目录 关于Pen改变Pen的宽度width和对齐方式Alignment带线帽的线段连接线条LineJoin自定义虚线用纹理填充线条 关于BrushHatchBrush阴影LinearGradientBrush线性渐变PathGradientBrush 详细示例Pen与Brush的属性与方法 关于Pen 改变Pen的宽度width和对齐方式Alignment 可以…

IntelliJ IDEA Ultimate 2024.1 Mac激活码 Java开发首选IDE

IntelliJ IDEA Ultimate 2024 搜Mac软件之家下载IDEA Mac中文版 IntelliJ IDEA Ultimate 2024是JetBrains公司推出的一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为专业开发者设计&#xff0c;支持多种编程语言和框架。它提供了一系列高级功能&…

【免费Web系列】JavaWeb实战项目案例五

这是Web第一天的课程大家可以传送过去学习 http://t.csdnimg.cn/K547r 新增员工 前面我们已经实现了员工信息的条件分页查询。 那今天我们要实现的是新增员工的功能实现&#xff0c;页面原型如下&#xff1a; ​ 首先我们先完成"新增员工"的功能开发&#xff0…

Linux--线程的分离、线程库的地址关系的理解、线程的简单封装(二)

线程系列&#xff1a; 线程的认识&#xff1a;讲解线程的概念和线程的基本控制 线程的分离 线程分离是指将一个线程从主线程中分离出来&#xff0c;使其能够独立运行。当一个线程被设置为分离状态时&#xff0c;它结束时系统会自动回收其资源&#xff0c;而不需要其他线程使用…

【喜报】科大睿智服务企业通过CMMI3级认证

​北京建投科信科技发展股份有限公司&#xff08;以下简称“北京建投科技” &#xff09;前身为北京银帝科技发展公司&#xff0c;成立于1993年&#xff0c;注册资本6,000万元&#xff0c;为中国建银投资有限责任公司&#xff08;简称“中国建投”&#xff09;的成员企业建投华…

ovs-vsctl错误:Port does not contain a column whoes name matches “--id“

出错的命令是: ovs-vsctl -- set Bridge br-int mirrors=@m -- --id=@snooper0 get Port snooper0\ -- --id=@patch-tun get Port patch-tun -- --id=@m create Mirror name=mymirror \ select

微软Edge浏览器深度解析:功能、同步、隐私与安全

微软Edge浏览器是微软公司开发的一款网页浏览器,它基于Chromium内核,提供了快速、安全和兼容性良好的网页浏览体验。以下是关于微软Edge浏览器的详细信息和使用指南: 微软Edge浏览器的主要特点: 1. 基于Chromium内核: 渲染引擎:Chromium内核是基于开源项目Blink的,它…

LNMP分布式搭建

一、准备三台主机 192.168.100.11 mysql 192.168.100.12 nginx 192.168.100.13 php 二、关闭防火墙及安全策略 systemctl stop firewalld setenforce 0 三、安装nginx&#xff08;192.168.100.11&#xff09; 1、添加nginx源 vim /etc/yum.repos.d/ng…

数据整理的Compact流程 (二)|OceanBase数据转储合并技术解读(二)

上篇文章《数据整理的Compact流程 &#xff08;一&#xff09;&#xff5c;OceanBase数据转储合并技术解读&#xff08;二&#xff09;》中&#xff0c;有讲解到&#xff0c;在OceanBase数据库中&#xff0c;当MemTable写满时&#xff0c;将其下刷到Mini SSTable的过程包含两个…

正邦科技(day4)

烧录 一、烧录固件二、 通讯模块升级1&#xff1a;USB的方式升级固件2&#xff1a;通过mqtt的方式升级固件3&#xff1a;切换环境 三、 烧录WiFi1&#xff1a;短接2&#xff1a;烧录脚本 设备注意事项&#xff1a; 第一种方式&#xff1a;通信模组和MCU都可以统一烧录BoodLoade…

数据结构---栈队列

栈和队列是我们数据结构中经常使用的数据结构&#xff0c;所以现在来了解一下栈和队列。 栈 特点&#xff1a; 栈是一种特殊的线性表&#xff0c;其中进行数据插入和弹出的部分叫做栈顶&#xff0c;另一端叫做栈底。 只允许数据从栈顶压入&#xff0c;从栈顶弹出即先进后出的…

Mac | Mac M 芯片应用意外退出问题

现象问题 电脑配置&#xff1a;MacBook Pro M1&#xff0c;系统 Sonoma 很多小伙伴新买了 M 芯片的 MacBook&#xff0c;在下载下应用后进行安装&#xff0c;安装成功后却无法打开&#xff0c;提示意外退出。报错如图 原因 部分应用过适配了 M 芯片&#xff0c;但还是有些应…

Windows配置共享文件夹

正文共&#xff1a;888 字 16 图&#xff0c;预估阅读时间&#xff1a;1 分钟 我们前面介绍了如果安装NAS工具&#xff08;废物利用&#xff0c;矿渣装个黑群晖。家庭小NAS搞起来&#xff01;&#xff09;&#xff0c;也介绍过如果配置远程桌面的多账号登录&#xff08;Windows…

Apache Nemo: A Framework for Optimizing Distributed Data Processing——论文泛读

TOCS 2021 Paper 论文阅读笔记整理 问题 针对资源和数据特性优化分布式数据处理的调度和通信&#xff0c;对于实现高性能至关重要。在最近的研究中广泛讨论的例子是&#xff1a;地理分布的资源[14&#xff0c;30&#xff0c;47&#xff0c;48]、廉价的瞬时资源[34&#xff0c…

五分钟“手撕”链表

为了提高大家的学习效率&#xff0c;我把代码放开头&#xff0c;供查阅。 目录 一、链表的实现代码 二、什么是链表 三、链表的分类 四、链表的常见操作 插入 删除 五、Java自带的LinkedList 两个构造方法 一些常用方法 六、LinkedList的遍历 七、ArrayList和Linke…

基恩士PLC与ModbusTCP转Profibus网关实现与激光设备的高效连接

本文将探讨如何通过使用基恩士PLC以及无锡耐特森ModbusTCP转Profibus网关来实现与激光设备的高效连接。在当今工业自动化领域&#xff0c;不同厂商的硬件设备和软件系统之间的互联互通性成为了提高生产效率、实现智能制造的关键因素。其中&#xff0c;可编程逻辑控制器&#xf…

spring boot 3.x版本 引入 swagger2启动时报错

一&#xff0c;问题 Spring Boot 3.x版本的项目里&#xff0c;准备引入Swagger2作为接口文档&#xff0c;但是项目启动报错&#xff1a; java.lang.TypeNotPresentException: Type javax.servlet.http.HttpServletRequest not present at java.base/sun.reflect.generics.…