Java设计模式:桥接模式

❤ 作者主页:欢迎来到我的技术博客😎
❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~*
🍊 如果文章对您有帮助,记得关注点赞收藏评论⭐️⭐️⭐️
📣 您的支持将是我创作的动力,让我们一起加油进步吧!!!🎉🎉

文章目录

  • 一、桥接模式的定义
  • 二、桥接模式的结构
  • 三、桥接模式的实现
  • 四、桥接模式的优缺点
  • 五、桥接模式的使用场景

一、桥接模式的定义

桥接模式(Bridge Pattern)是一种结构型设计模式,它将 抽象部分与其实现部分分离,使它们可以独立变化。桥接模式通过将抽象和实现分离,使得它们可以独立演化,互不影响。这种模式通过组合而不是继承的方式来实现抽象与实现的解耦。


二、桥接模式的结构

桥接模式包含以下的重要角色:

  • 抽象角色(Abstraction): 定义了抽象类的接口,维护一个指向实现部分的引用。抽象部分的主要责任是将客户端的请求委派给实例化角色,并可以包含一些自己的业务逻辑。抽象角色可以是抽象类或接口。
  • 具体抽象角色(Refined Abstraction): 扩展了抽象角色定义的接口,通常是对抽象角色的更具体的实现。具体抽象角色的变化不影响实现部分。
  • 实例化角色(Implementor): 定义了实现类的接口,供具体的实现类实现。实例化角色通常是一个接口,它与抽象角色的接口可能不完全一致。实例化角色的变化不影响抽象角色。
  • 具体实例化角色(Concrete Implementor): 实现了实例化接口的具体类。具体实现部分是抽象角色的实际执行者,它的变化不影响抽象角色。

三、桥接模式的实现

需求案例:在生活中使用遥控器来控制电视机,不同品牌的电视机有不同的功能和操作方式。而遥控器上的按钮则负责执行一些基本的功能,如开关、音量调节、频道切换等。

这里的桥接模式体现在遥控器和电视机之间的关系。具体的遥控器(抽象角色)可以独立于具体的电视机(实例化角色)变化,而新增一种电视机或遥控器不会影响到另一方。

  • 抽象角色 - 遥控器按钮: 包括开关按钮、音量调节按钮、频道切换按钮等。
  • 实例化角色 - 电视机: 包括不同品牌的电视机,如三星、索尼等。

使用桥接模式实现上述案例。类图如下:
在这里插入图片描述
 
具体的类设计如下:

实例化角色(电视):

public interface TV {

    void turnOn(); //打开电视

    void changeChannel(int channel); //切换频道

    void turnOff(); //关闭电视
}

具体实例化角色(三星电视机):

public class SamsungRemote extends RemoteControl {

    public SamsungRemote(TV tv) {
        super(tv);
    }

    @Override
    public void control(Integer channel) {
        tv.turnOn();
        tv.changeChannel(channel);
        tv.turnOff();
    }
}

具体实例化角色(索尼电视机):

public class SonyTV implements TV {

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

    @Override
    public void changeChannel(int channel) {
        System.out.println("电视已切换到" + channel + "频道");
    }

    @Override
    public void turnOff() {
        System.out.println("电视已关闭!");
    }
}

抽象角色(遥控器):

public abstract class RemoteControl {

    protected TV tv;

    public RemoteControl(TV tv) {
        this.tv = tv;
    }

    public abstract void control(Integer channel);
}

具体抽象角色(三星遥控器):

public class SamsungRemote extends RemoteControl {

    public SamsungRemote(TV tv) {
        super(tv);
    }

    @Override
    public void control(Integer channel) {
        tv.turnOn();
        tv.changeChannel(channel);
        tv.turnOff();
    }
}

具体抽象角色(索尼遥控器):

public class SonyRemote extends RemoteControl  {

    public SonyRemote(TV tv) {
        super(tv);
    }

    @Override
    public void control(Integer channel) {
        tv.turnOn();
        tv.changeChannel(channel);
        tv.turnOff();
    }
}

客户端类:

public class Client {

    public static void main(String[] args) {

        System.out.println("------使用三星电视机------");
        SamsungRemote samsungRemote = new SamsungRemote(new SamsungTV());
        samsungRemote.control(5);

        System.out.println("------使用索尼电视机------");
        SonyRemote sonyRemote = new SonyRemote(new SonyTV());
        sonyRemote.control(10);
    }

}

测试结果如下:
在这里插入图片描述
 
可以看到,这样设计的好处在于,遥控器和电视机两个维度可以独立变化,新增一种电视机或遥控器不会影响到另一方,符合桥接模式的思想。


四、桥接模式的优缺点

优点:

  1. 解耦抽象和实现: 桥接模式通过将抽象部分和实现部分分离,使它们可以独立变化。这降低了它们之间的耦合度,使系统更灵活。
  2. 多维度扩展: 桥接模式支持多维度的扩展。可以轻松地新增新的抽象部分或实现部分,而不影响已有的部分,提高了系统的可扩展性。
  3. 简化继承体系: 桥接模式避免了采用多层次的继承体系,减少了类之间的耦合。通过组合和委托关系,代码更易于理解、扩展和维护。
  4. 提高可维护性: 分离抽象和实现部分使得代码更清晰、可读性更好。通过合理的组织结构,增加了代码的可维护性。

缺点:

  1. 增加系统复杂性: 在小规模系统中,桥接模式可能显得过于繁琐,增加了代码的复杂性。只有在系统中存在多个变化维度,并且这些维度需要独立变化时,桥接模式才更有价值。
  2. 引入抽象和实现的额外复杂性: 引入抽象和实现部分的分离可能会增加设计的复杂性,特别是在对系统有深刻理解之前。
  3. 需要正确识别变化维度: 如果无法正确识别系统中存在的变化维度,就难以设计出合适的抽象和实现分离的结构,可能导致不必要的复杂性。

五、桥接模式的使用场景

桥接模式适用于以下场景:

  1. 多维度变化: 当一个类存在多个独立变化的维度,且这些维度需要独立扩展时,使用桥接模式可以有效地将它们分离,使系统更灵活。
  2. 抽象和实现的解耦: 当需要避免在抽象部分和实现部分之间建立静态的继承关系时,桥接模式提供了一种更加灵活的设计方式,可以通过组合和委托来实现抽象和实现的解耦。
  3. 多继承结构: 当系统中的类层次结构存在多层继承,而且这种多层次的继承关系导致类的数量爆炸性增长时,桥接模式可以减少继承层次,使系统更加清晰、易于理解和维护。
  4. 不同维度的独立变化: 当系统中的不同维度的变化需要独立进行时,桥接模式可以有效地应对这种情况,使得各个维度的变化互不影响。
  5. 可插拔的组件: 桥接模式可以用于设计可插拔的组件,即可以在运行时动态地选择和切换抽象和实现部分,而不影响客户端代码。

 
非常感谢您阅读到这里,如果这篇文章对您有帮助,希望能留下您的点赞👍 关注💖 分享👥 留言💬thanks!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【STL】deque双端开口容器

1.关于deque容器说明 deque容器与vector容器差不多,但deque是双端开口容器,可以在两端插入和删除元素 push_front( )//在头部插入 push_back( )//在尾部插入 pop_front( )//在头部删除 pop_back( ) //在尾部删除 其他相应函数与vector差不多&#…

Pytorch入门-TensorBoard

文章目录 WhatHOWSummaryWriter What TensorBoard是TensorFlow自带的一个强大的可视化工具,也是一个Web应用程序套件。 torch.utils.tensorboard 是 PyTorch 提供的一个用于将标量、图像、直方图和其他信息记录到 TensorBoard 中的实用程序包。TensorBoard 是 Tenso…

Pycharm的Project Structure (项目结构)

文章目录 一、Sources二、Tests三、Exeluded四、Namespace packages五、Templates六、Resources 一、Sources 源代码根目录:包含项目的主要源代码,它会在这个目录下搜索代码,然后自动补全和只能提示都通过这里的代码提供。若项目运行自定义代…

rabbitmq-spring-boot-start配置使用手册

rabbitmq-spring-boot-start配置使用手册 文章目录 1.yaml配置如下2.引入pom依赖如下2.1 引入项目resources下libs中的jar包依赖如下2.2引入maven私服依赖如下 3.启动类配置如下4.项目中测试发送消息如下5.项目中消费消息代码示例6.mq管理后台交换机队列创建及路由绑定关系如下…

Java算法总结之冒泡排序(详解)

程序代码园发文地址:Java算法总结之冒泡排序(详解)-程序代码园小说,Java,HTML,Java小工具,程序代码园,http://www.byqws.com/ ,Java算法总结之冒泡排序(详解)http://www.byqws.com/blog/3145.html?sourcecsdn 冒泡排序…

(day 7)JavaScript学习笔记(函数1)

概述 这是我的学习笔记,记录了JavaScript的学习过程,我是有一些Python基础的,因此在学习的过程中不自觉的把JavaScript的代码跟Python代码做对比,以便加深印象。在写博客的时候我会尽量详尽的记录每个知识点。如果你完全没接触过J…

社媒营销会遇到的封号问题

最近看到很多的直播都在教伙伴们怎么用linked in 以及facebook开发客户,比如如何添加联系人,如何用添加好友的话术,如何加群,如何分析客户的背景等等。 有的主播只是讲一些表面的东西,有的主播可能是真的肚子里有货&a…

【DataWhale学习】用免费GPU线上跑StableDiffusion项目实践

用免费GPU线上跑SD项目实践 ​ DataWhale组织了一个线上白嫖GPU跑chatGLM与SD的项目活动,我很感兴趣就参加啦。之前就对chatGLM有所耳闻,是去年清华联合发布的开源大语言模型,可以用来打造个人知识库什么的,一直没有尝试。而SD我…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:StepperItem)

用作Stepper组件的页面子组件。 说明: 该组件从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 子组件 支持单个子组件。 接口 StepperItem() 属性 参数名参数类型参数描述prevLabelstring设置左侧文本按钮内…

硬件软件_驱动程序只有cat,inf,sys,怎么安装?

硬件软件_驱动程序只有cat,inf,sys,怎么安装? 右键点击inf文件 -》 安装 即可完成。

文件外发管理软件(控制文件外发的软件·精选推荐)

无论是与合作伙伴共享资料、还是员工需要在家办公时访问公司内部文件,文件的外发都是必要的。然而,这也带来了数据泄露的风险。 如果没有有效的管理手段,敏感信息可能会被未授权的人员获取,进而对企业的商业机密、客户隐私和知识…

Excel查找函数的高级用法

查找在实际工作中是经常遇到的,那你会查找吗?本期与大家分享6个查找函数技巧。 一、查找的基础用法 1、根据内容查找相应的行数 想知道数据在区域中的位置,可以用MATCH函数。 举个例子,查找“刘冰”在姓名列中所在的函数。 输…

Web-based DBMS Technology 线上数据库

Example Online Databases • https://www.planespotters.net/ • https://www.comics.org/ • https://www.quandl.com/ • https://www.enigma.com/ • https://www.sportradar.com/ Basics of WWW • The Web is a very large client-server system — Connected through r…

Anaconda的使用及spyder相关设置

Anaconda Anaconda是一个Python发行版,主要用于数据科学和机器学习领域。Anaconda集成了许多常用的数据科学工具和库,如NumPy、Pandas、Scikit-learn等,同时还包含了一个强大的包管理器conda和一个集成开发环境Spyder。Anaconda的目标是提供一…

电脑回收站图标更改

小猫图标 效果图 1.下载压缩包 https://www.123pan.com/s/9QRqVv-u3lY.html 解压后得到两个文件 coo.dll(满) ooo.dll(空)把这两个文件放到C盘的图片文件夹中 2.更改图标 wini打开设置,选择个性化&#xff0c…

Python学习笔记1:Pycharm首次安装环境搭建汉化

Pycharm首次安装环境搭建汉化笔记 1.下载网址 首先下载专业版的pycharm,这里建议下载专业版是因为功能更全面,社区版的往往没有远程调控等实践功能。 网址贴在下方: https://www.jetbrains.com/pycharm/download/?sectionwindows •Profe…

Vue3组件详情

Vue3组件详情 一、父组件向子组件传值 ref、props二、子组件向父组件传值 emit三、子组件向父组件传值 v-model四、setup语法糖1、基本用法2、data和methods3、计算属性 computed4、监听器 watch、watchEffect5、自定义指令 directive6、import导入的内容可以直接使用7、声明pr…

【Docker】使用Docker部署IT运维管理平台CAT

作者怀揣着一个美好的愿景,旨在提升管理效率、推动开源项目的蓬勃发展。 来一杯咖啡与茶,为 IT 运维从业者减轻管理负担,提升管理效率,从繁重无序的工作中解压出来,利用剩余时间多喝一杯休息一下。 这是一个专为 IT 运…

英伟达推出免训练,可生成连贯图片的文生图模型ConsiStory,生成角色一致性解决新方案

目前,多数文生图模型皆使用的是随机采样模式,使得每次生成的图像效果皆不同,在生成连贯的图像方面非常差。 例如,想通过AI生成一套图像连环画,即便使用同类的提示词也很难实现。虽然DALLE 3和Midjourney可以对图像实现…

k8s+zabbix

一,环境: 1),k8s部署,master和node节点都部署成功 二,部署: 1),安装python3(资源中有) wget https://www.python.org/ftp/python/3.7.4/Python-…