设计模式之桥接模式释义与举例剖析

news2025/2/27 23:16:15

文章目录

  • 一、前言
  • 二、模式定义
  • 三、模式结构
  • 四、案例具体实现
  • 五、 模式优缺点
  • 六、 模式使用场景
  • 七、 模式总结

一、前言

开始学Java讲继承的时候,总喜欢用一个例子来讲解,那就是画图形。这里有一个画笔,可以画正方形、长方形、圆形。除了画出指定的图形形状之外,还需要给图形进行上色。这里有三种颜色:白色灰色黑色。我们可以画出9种图形,白色正方形、白色长方形、白色圆形…。

好,我们开始动手了,老师说要求画出圆形、正方形,并给他们涂上蓝色、红色,分别是红色圆形红色正方形蓝色圆形蓝色正方形
在这里插入图片描述
老师看了看你提交的作业,非常的满意。之后突发奇想,在加上青色,灰色,绿色的颜色。形状在加上``长方形,三角形。这样一想,还要建立20个类

抛开设计模式不说:如果是日常生活中,我们会如何处理这种情况。一般会将所有的情况都放到两个集合中,你需要什么我就去两个集合中取出对应的属性。
在这里插入图片描述

很明显可以看出来,对于这个问题有两个个变化的维度,分别是形状和颜色。对于这种有多个变化纬度的组合问题,一般采用上述的第二种方式,这样除了减少系统中的类个数,也利于系统扩展。对于方案二的应用我们称之为桥接模式。
在这里插入图片描述

二、模式定义

桥接模式即将抽象部分与它的实现部分分离开来,使他们都可以独立变化。

桥接模式将继承关系转化成关联关系,它降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量。

这里的抽象部分与实现部分分离开
不是将抽象类与他的派生类分离,而是抽象类和它的派生类用来实现自己的对象。这句话可能还不是很好理解,按照上面的例子来说明,实现系统可能有多个角度分类,如上中,颜色和形状在不断的变化,以前是直接利用图形的抽象,图形的实现,然后给每个图形进行painting
现在就是,将图形的抽象和图形的实现分离开来,让**多角度分类(颜色,形状)**分离,让他们独立变化,减少他们的耦合。

要理解桥接模式,重点需要理解如何将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化。

  • 抽象化:抽象化就是忽略一些信息,把不同的实体当作同样的实体对待。在面向对象中,将对象的共同性质抽取出来形成类的过程即为抽象化的过程。
  • 实现化:针对抽象化给出的具体实现,就是实现化,抽象化与实现化是一对互逆的概念,实现化产生的对象比抽象化更具体,是对抽象化事物的进一步具体化的产物。
  • 脱耦:脱耦就是将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联,将两个角色之间的继承关系改为关联关系。桥接模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用关联关系(组合或者聚合关系)而不是继承关系,从而使两者可以相对独立地变化,这就是桥接模式的用意。

三、模式结构

桥接模式包含如下角色:

  • Abstraction:抽象类
  • RefinedAbstraction:扩充抽象类
  • Implementor:实现类接口
  • ConcreteImplementor:具体实现类

在这里插入图片描述
在这里插入图片描述

四、案例具体实现

对于上图中,利用上述画画的例子一一进行对照。

tips: 当然,也可以将color作为Abstraction抽象类,是一样去实现的,下面只是提供一种实现方法。

在这里插入图片描述

按照第一次举的例子:Abstraction 就是Shape

public abstract class Shape {

	 abstract void draw(); // opertion()
	 
    Color color;
    public void setColor(Color color){
        this.color = color;
    }
}

而对于RefinedAbstraction,扩充抽象类,这里不一定就是抽象类,也可以是具体的实现类。这里我直接让各种形状继承Shape

public class Circle extends Shape{

    @Override
    void draw() {
        color.bepaint("圆形");
    }
}

public class Rectangle extends Shape{
    @Override
    public void draw() {
        color.bepaint("长方形");
    }
}

public class Square extends Shape{

    @Override
    void draw() {
        color.bepaint("正方形");
    }
}

对于Implementor:实现类接口,这里我定义的是颜色。

public interface Color {
    // 画颜色
    void bepaint(String shape);
}

ConcreteImplementor:具体实现类

public class Black implements Color{

   @Override
   public void bepaint(String shape) {
       System.out.println("黑色的" + shape);
   }
}

public class Gray implements Color{

   @Override
   public void bepaint(String shape) {
       System.out.println("灰色的" + shape);
   }
}

public class White implements Color{

   @Override
   public void bepaint(String shape) {
       System.out.println("白色的" + shape);
   }
}

对于client

public class Client {
    public static void main(String[] args) {
        // 创建第一个类
        Color white = new White();
        // 正方形
        com.fckey.design.bridge.Square squareBridge = new com.fckey.design.bridge.Square();
        // 白色的正方形
        squareBridge.setColor(white);
        squareBridge.draw();

        // 圆形
        com.fckey.design.bridge.Circle circle = new com.fckey.design.bridge.Circle();
        circle.setColor(white);
        circle.draw();
    }
}

对于Client使用组合对象时的时序图
在这里插入图片描述

五、 模式优缺点

  • 优点
    1、分离抽象接口及其实现部分。提高了比继承更好的解决方案。
    2、桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
    3、实现细节对客户透明,可以对用户隐藏实现细节。

  • 缺点

    1、桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
    2、桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。

六、 模式使用场景

1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

七、 模式总结

对于桥接模式,我认为最大的作用就是能够防止类爆炸问题,将继承转变为组合的方式,可以对系统进行解耦。对于桥接模式通常是预先设计的,让您可以独立开发应用程序的各个部分。另一方面,适配器模式通常与现有应用程序一起使用,以使一些原本不兼容的类可以很好地协同工作

桥接、状态、策略(在某种程度上还有适配器)具有非常相似的结构 。实际上,所有这些模式都基于组合即将工作委托给其他对象。然而,它们都解决了不同的问题。模式不仅仅是以特定方式构建代码的秘诀。它还可以与其他开发人员交流该模式解决的问题

您可以将Abstract FactoryBridge一起使用。当Bridge定义的某些抽象只能用于特定实现时,这种配对很有用。在这种情况下,抽象工厂可以封装这些关系并向客户端代码隐藏复杂性。

还可以将 BuilderBridge结合使用:director 类扮演抽象的角色,而不同的构建器充当实现。

本博文设计到的完整代码 : GitHub 完整代码


参考
桥接模式最核心的思想
design-patterns bridge
桥接设计模式,有效的减少类爆炸!
桥接模式优缺点
菜鸟教程/桥接模式

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

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

相关文章

OpenCV-答题卡识别-四点透视变换

目录 答题卡识别图片读取四点透视变换 划出区域处理选择题区域处理准考证号区域处理科目区域得分导出结果 封装成品 答题卡识别 使用opencv技术,实现对答题卡的自动识别,并进行答题结果的统计 技术目的: 能够捕获答题卡中的每个填涂选项;将…

【新星计划-2023】TCP三次握手和四次挥手讲解

关于TCP三次握手和四次挥手,各位想必在读大学的时候或者是在面试的时候一定遇到过,三次握手和四次挥手本身是不是太难的,但它容易忘😞,今天我就在这里给大家讲解一下三次握手与四次挥手。 一、三次挥手 TCP三次握手建…

我,大厂P9,找不到工作

作者| 老W 编辑| Emma 来源| 技术领导力(ID:jishulingdaoli) K哥写在前面的话:这是一位读者投稿,读者老W讲述了自己从大厂P9失业后、再就业的故事,并总结了自己的心路历程,很真实的记录与思考,值得大家借…

SensorX2car:在道路场景下的完成传感器到车体坐标系标定

文章:SensorX2car: Sensors-to-car calibration for autonomous driving in road scenarios 作者:Guohang Yan, Zhaotong Luo, Zhuochun Liu and Yikang Li 编辑:点云PCL 代码:https://github.com/OpenCalib/SensorX2car 作者单位…

IDEA+maven+Springboot工程创建超详细过程示例

IDEAmavenSpringboot工程创建超详细过程示例 1、IDEA、Maven下载安装及IDEA配置Maven教程2、IDEAmavenSpringboot的web工程创建示例2.1 SpringBoot简介2.2 maven形式创建sprintboot工程2.3 导入相关依赖2.4 创建SpringBoot启动类2.5 创建 Controller2.6 启动项目2.7 配置端口信…

springboot第22集:security,Lombok,token,redis

Spring Security是一个基于Spring框架的权限管理框架,用于帮助应用程序实现身份验证和授权功能。它可以为Web应用程序、REST API和方法级安全性提供支持,并支持各种认证方式。 Spring Security最初是Acegi Security的前身,但由于其配置繁琐而…

【第六期】Apache DolphinScheduler 每周 FAQ 集锦

点击蓝字 关注我们 摘要 为了让 Apache DolphinScheduler 的广大用户和爱好者对于此项目的疑问得到及时快速的解答,社区特发起此次【每周 FAQ】栏目,希望可以解决大家的实际问题。 关于本栏目的要点: 本栏目每周将通过腾讯文档(每…

用排列组合来编码通信(六)——魔术《5张牌的预言》的魔术拓展之《My Fitch Four Glory》...

早点关注我,精彩不错过! 在上一篇中,我们介绍了《5张牌的预言》这个魔术的一个精彩的扩展表演《Eigens Value》,把这个魔术和数学性质的结合做到了极致,相关内容请戳: 用排列组合来编码通信(五&…

第二十二章 Unity 光照贴图

光照贴图过程将预先计算场景中静态物体表面的亮度,并将结果存储在称为“光照贴图”的纹理中供以后使用。光照贴图可以包含直接光照和间接光照,以及阴影效果。但是,烘焙到光照贴图中的数据无法在运行时更改,这就是为什么移动静态物…

Angular开发之——Angular介绍(01)

一 概述 Angular是什么AngularJS和Angular关系Angular特性Angular的发展历史Angular学习建议 二 Angular是什么 Angular(读音[ˈŋɡjələr])是一套用于构建用户界面的javaScript框架。由Google开发和维护,主要被用来开发单页面应用程序类似于Vue.js(MVVM数据驱动…

视觉检测技术在图书生产缺陷控制中的应用

在过去我们一直向大家展示的是视觉检测应用在重工业制造之上,让很多人误以为这种新兴的检测技术更加倾向于重工业,或者说因为成本因素,这项技术对目前的轻工业来说更加的不友好,其实并不是这样的。 轻工业我们之所以很少的提机器…

docker入门和docker应用场景,镜像制作,服务编排,docker私服

一、简介 docker解决了什么问题docker和虚拟机的区别在CentOS7里安装docker 1. docker简介 我们写的代码会接触到好几个环境:开发环境、测试环境以及生产环境等等。多种环境去部署同一份代码,由于环境原因往往会出现软件跨环境迁移的问题(也就…

黏包和半包

黏包和半包 黏包: Slf4j public class HelloWorldServer {public static void main(String[] args) {NioEventLoopGroup boss new NioEventLoopGroup();NioEventLoopGroup worker new NioEventLoopGroup();try {ServerBootstrap serverBootstrap new ServerBoo…

open3d教程(二):可视化三维模型,并转换成点云(Python版本)

1、三维模型获取 可以自己用建模软件建立一个模型从free3d免费下载 2、关键函数 open3d.visualization.draw_geometries 参数: geometry_list(List[open3d.geometry.Geometry]):要可视化的几何体列表.window_name(str, optional, defaultOpen3D)&…

Linux环境下编程遇到“fatal error:stdio.h:没有那个文件或目录”错误解决办法

我是荔园微风,作为一名在IT界整整25年的老兵,今天总结一下linux环境下如何解决一个常见的问题,也就是“fatal error:stdio.h:没有那个文件或目录”错误。 不少初学者在linux环境下用gcc编译C语言时,经常会遇到这个问题。 比如当…

工具推荐二

(点击上方公众号,可快速关注) GUI框架 我是个后端程序员,使用GUI框架的机会很少,主要用来编写个人或工作中的一些小工具上,经验有限,仅供参考。 Tk框架这个框架tcl语言自带,在python…

海报图片生成服务在狐友的落地实践

本文字数:22817字 预计阅读时间:58分钟 项目背景 狐友作为搜狐的一款社交产品,在流量传播上有着旺盛的需求点。而在流量传播所需的众多载体之中,海报图片以其简单的分享形式、可定制的视觉体验、自带二维码识别导流等特点&#xf…

入门与 Follow GPT 的路径分析:LLM 道阻且长,行则将至

动手点关注 干货不迷路 本文只用于技术交流,仅代表作者个人观点。 作为 CEO,Sam 将 OpenAI 的内部氛围组织的很好,有位 OpenAI 的前员工告诉拾象团队,当 2018 年 GPT-2 的论文被驳回时,Sam 在团队周会上将拒信的内容朗…

ONES X 高测股份|用数字化,重构新材料企业的研发管理体系

近日,ONES 签约高硬材料切割的领军企业——高测股份,助力高测股份建立有效、规范的研发测试管理体系,实现项目管理、测试管理、知识库管理、工时管理、组织效能管理等端到端的研发管理,提升测试效率和产品交付质量,并进…

用Python+OpenCV+Yolov5+PyTorch开发的车牌识别软件(包含训练数据)

目录 演示视频 软件使用说明 软件设计思路 演示视频 这是一个可以实时识别车牌的软件,支持图片和视频识别,以下是软件的演示视频。 车牌识别软件 点击查看代码购买地址 软件使用说明 1. 下载源码后,首先安装依赖库。项目所用到的依赖库已…