桥接模式——处理多维度变化

1、简介

1.1、概述

桥接模式是一种很实用的结构型设计模式。如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合单一职责原则。与多层继承方案不同,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,该关联关系类似一条连接两个独立继承结构的桥,故名桥接模式。

桥接模式用一种巧妙的方式处理多层继承存在的问题。桥接模式采用抽象关联取代了传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效控制了系统中类的个数。

1.2、定义

将抽象部分与其实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

2、解析

2.1、UML类图

桥接模式的结构与其名称一样,存在一条连接两个独立继承等级结构的桥。桥接模式结构如下图所示:

在这里插入图片描述
可以看出,在桥接模式结构图中包含以下4个角色。

  1. Abstraction(抽象类):用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义了一个Implementor(实现类接口)类型的对象并可以维护该对象。抽象类与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。
  2. RefinedAbstraction(扩充抽象类):扩充由Abstraction定义的接口,通常情况下它不再是抽象类而是具体类。扩充抽象类实现了在Abstraction中声明的抽象业务方法,在RefinedAbstraction中可以调用在Implementor中定义的业务方法。
  3. Implementor(实现类接口):定义实现类的接口,这个接口不一定要与Abstraction的接口完全一致,事实上这两个接口可以完全不同。一般而言,Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多、更复杂的操作。Implementor接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系,在Abstraction中不仅拥有自己的方法,还可以调用到Implementor中定义的方法,使用关联关系来替代继承关系。
  4. ConcreteImplementor(具体实现类):具体实现Implementor接口,在不同的ConcreteImplementor中提供基本操作的不同实现。在程序运行时,ConcreteImplementor对象将替换其父类对象,提供给抽象类具体的业务操作方法。

桥接模式是一个非常有用的模式,在桥接模式中体现了很多面向对象设计原则的思想,包括单一职责原则、开闭原则、合成复用原则、里氏代换原则、依赖倒转原则等。熟悉桥接模式有助于深入理解这些设计原则,也有助于形成正确的设计思想和培养良好的设计风格。

在使用桥接模式时,首先应该识别出一个类所具有的两个独立变化的维度,将它们设计为两个独立的继承等级结构,为两个维度都提供抽象层,并建立抽象耦合。通常情况下,将具有两个独立变化维度的类的一些普通业务方法和与之关系最密切的维度设计为抽象类层次结构(抽象部分),而将另一个维度设计为实现类层次结构(实现部分)。

2.2、代码示例

在具体编码实现时,由于在桥接模式中存在两个独立变化的维度,为了使两者之间耦合度降低,首先需要针对两个不同的维度提取抽象类和实现类接口,并建立一个抽象关联关系。对于“实现部分”维度,典型的实现类接口代码如下:

interface Implementor{public void operationimpl();
}

在实现Implementor接口的子类中实现了在该接口中声明的方法,用于定义与该维度相对应的一些具体方法。

对于另一“抽象部分”维度而言,其典型的抽象类代码如下:

abstract class Abstraction{// 定义实现类接口对象protected Implementor impl;public void setImpl(Implementor impl){this.impl=impl;}// 声明抽象业务方法public abstract void operation();
}

在抽象类Abstraction中定义了一个实现类接口类型的成员对象impl,再通过注入的方式给该对象赋值,一般将该对象的可见性定义为protected,以便在其子类中访问Implementor的方法。Abstraction类的子类一般称为扩充抽象类或细化抽象类(RefinedAbstraction),典型的RefinedAbstraction类代码如下:

class RefinedAbstraction extends Abstraction{public void opration(){// 业务代码impl.operationimpl(); // 调用实现类的方法// 业务代码}
}

对于客户端而言,可以针对两个维度的抽象层编程。在程序运行时再动态确定两个维度的子类,动态组合对象,将两个独立变化的维度完全解耦,以便能够灵活地扩充任一维度而对另一维度不造成任何影响。

3、适配器模式与桥接模式的联用

在软件开发中,适配器模式通常可以与桥接模式联合使用。适配器模式可以解决两个已有接口间不兼容问题,在这种情况下被适配的类往往是一个黑盒子,有时候用户不想也不能改变这个被适配的类,也不能控制其扩展。适配器模式通常用于现有系统与第三方产品功能的集成,采用增加适配器的方式将第三方类集成到系统中。桥接模式则不同,用户可以通过接口继承或类继承的方式来对系统进行扩展。

桥接模式和适配器模式用于设计的不同阶段。桥接模式用于系统的初步设计,对于存在两个独立变化维度的类可以将其分为抽象类和实现类两个角色,使它们可以分别进行变化;而在初步设计完成之后,当发现系统与已有类无法协同工作时,可以采用适配器模式。但有时候在设计初期也需要考虑适配器模式,特别是那些涉及大量第三方应用接口的情况。

4、桥接模式总结

桥接模式是设计Java虚拟机和实现JDBC等驱动程序的核心模式之一,应用较为广泛。在软件开发中,如果一个类或一个系统有多个变化维度时,都可以尝试使用桥接模式对其进行设计。桥接模式为具有多维度变化的系统提供了一套完整的解决方案,并且降低了系统的复杂度。

4.1、优点

  1. 分离抽象接口及其实现部分。桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化(即抽象和实现不再在同一个继承层次结构中,而是“子类化”它们,使它们各自都具有自己的子类,以便任意组合子类,从而获得多维度组合对象)。
  2. 在很多情况下,桥接模式可以取代多层继承方案。多层继承方案违背了单一职责原则,复用性较差,且类的个数非常多。桥接模式是比多层继承方案更好的解决方法,它极大地减少了子类的个数。
  3. 桥接模式提高了系统的可扩展性。在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合开闭原则。

4.2、缺点

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

4.3、适用场景

  1. 如果一个系统需要在抽象类和具体类之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。
  2. 抽象部分和实现部分可以以继承的方式独立扩展而互不影响,在程序运行时可以动态地将一个抽象类子类的对象和一个实现类子类的对象进行组合,即系统需要对抽象类角色和实现类角色进行动态耦合。
  3. 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。
  4. 对于那些不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。

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

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

相关文章

游戏APP开发:创新设计的秘诀

在游戏 APP开发中,创新设计是游戏开发公司的一大追求,为了可以为用户带来更好的游戏体验,这就需要对游戏 APP开发进行创新设计。那么,游戏 APP开发中的创新设计是什么呢?接下来,我们就一起来看看吧。 想要…

mongodb docker 及常用命令

MongoDB属于非关系型数据库,它是由C编写的分布式文档数据库。内部使用类似于Json的bson二进制格式。 中文手册 https://www.w3cschool.cn/mongodb/ 安装 https://www.mongodb.com/try/download/community 二进制安装可见另一篇: centos7 mongodb 4.0.28…

SSL原理详解

SSL协议结构: SSL协议分为两层,下层为SSL记录协议,上层为SSL握手协议、SSL密码变化协议和SSL警告协议。 1.下层为SSL记录协议,主要作用是为高层协议提供基本的安全服务 建立在可靠的传输之上,负责对上层的数据进行分块…

Vue3+Vite+TypeScript常用项目模块详解

目录 1.Vue3ViteTypeScript 概述 1.1 vue3 1.1.1 Vue3 概述 1.1.2 vue3的现状与发展趋势 1.2 Vite 1.2.1 现实问题 1.2 搭建vite项目 1.3 TypeScript 1.3.1 TypeScript 定义 1.3.2 TypeScript 基本数据类型 1.3.3 TypeScript语法简单介绍 2. 项目配置简单概述 2.…

小白到运维工程师自学之路 第六十三集 (dockerfile安装sshd、httpd、nginx)

一、概述 Dockerfile的指令根据作用可以分为两种,构建指令和设置指令。构建指令用于构建image,其指定的操作不会在运行image的容器上执行;设置指令用于设置image的属性,其指定的操作将在运行image的容器中执行。 1、FROM 镜像:T…

em3288 linux_4.19 sd卡调试

默认配置,根据实际配置即可。

Maven-学习笔记

文章目录 1. Maven简介2.Maven安装和基础配置3.Maven基本使用4.Maven坐标介绍 1. Maven简介 概念 Maven是专门用于管理和构建Java项目的工具 主要功能有: 提供了一套标准化的项目结构提供了一套标准化的构建流程(编译,测试,打包,…

语音识别 — 特征提取 MFCC 和 PLP

一、说明 语音识别是一种技术,通过计算机和软件系统,将人们的口头语言转换为计算机可读的文本或命令。它使用语音信号处理算法来识别和理解人类语言,并将其转换为计算机可处理的格式。语音识别技术被广泛应用于许多领域,如语音助手…

什么是图像特征?如何让计算机理解图像特征?

图像的特征 大多数人都玩过拼图游戏。首先拿到完整图像的碎片,然后把这些碎片以正确的方式排列起来从而重建这幅图像。如果把拼图游戏的原理写成计算机程序,那计算机就也会玩拼图游戏了。 在拼图时,我们要寻找一些唯一的特征,这…

企业AD域管理:ADManager Plus助您轻松掌控全局

在现代企业中,Active Directory(AD)域是一个至关重要的组成部分。它作为一种身份验证和授权机制,管理着企业网络中的用户、计算机、组和其他资源。然而,随着企业规模和复杂性的不断增长,AD域的管理变得越来…

ELK 企业级日志分析系统(一)

目录 一、ELK 简介 1.1 组件说明 1.2 为什么要使用ELK 1.3 完整日志系统的基本特征 1.4 ELK工作原理 二、Elasticsearch的介绍 2.1 Elasticsearch的核心: 三、Logstash 3.1 Logstash简介 四、Kibana 五、部署ELK日志分析系统 5.1 服务器配置 5.2 ELK Elasticse…

苹果电脑系统优化工具:Ventura Cache Cleaner for mac

Ventura Cache Cleaner for Mac是一款专门为苹果电脑开发的系统优化工具,旨在帮助用户清理和优化Mac电脑,提高系统性能和速度。该软件由美国公司Northern Softworks开发,已经推出了多个版本,适用于不同版本的Mac操作系统。 Ventu…

常见OOM异常分析排查

常见OOM异常分析排查 Java内存溢出Java堆溢出原因解决思路总结 Java内存溢出 java堆用于存储对象实例,如果不断地创建对象,并且保证GC Root到对象之间有可达路径,垃圾回收机制就不会清理这些对象,对象数量达到最大堆的容量限制后就会产生内存溢出异常. Java堆溢出原因 无法在…

【IMX6ULL驱动开发学习】21.Linux驱动之PWM子系统(以SG90舵机为例)

1.设备树部分 首先在 imx6ull.dtsi 文件中已经帮我们定义好了一些pwm的设备树节点&#xff0c;这里以pwm2为例 pwm2: pwm02084000 {compatible "fsl,imx6ul-pwm", "fsl,imx27-pwm";reg <0x02084000 0x4000>;interrupts <GIC_SPI 84 IRQ_TYP…

开源-基于ch9374b的KVM设计

文章目录 简介功能特性设计图实现功能开源链接 简介 平时总有一种需求&#xff0c;就是我在调试树莓派的时候&#xff0c;经常要在pc电脑和开发板之间来回操作&#xff0c;因此就需要两套键盘和鼠标&#xff0c;但是我的桌子实在是太小了&#xff0c;两套键鼠不能并排放置&…

13 springboot项目——准备数据和dao类

13.1 静态资源下载 https://download.csdn.net/download/no996yes885/88151513 13.2 静态资源位置 css样式文件放在static的css目录下&#xff1b;static的img下放图片&#xff1b;template目录下放其余的html文件。 13.3 创建两个实体类 导入依赖&#xff1a;lombok <!…

桥接模式(Brige)

桥接模式是一种结构型设计模式&#xff0c; 又称为柄体(Handle and Body)模式或接口(Interface)模式。桥接模式&#xff0c;可将将抽象部分与它的实现部分分离&#xff0c;使它们都可以独立地变化。如将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构&#x…

百度:文心千帆 网页搭建和示例测评

文章目录 官方文档代码示例token获取流式回答官网完整示例 制作一个网页端 官方文档 https://cloud.baidu.com/doc/WENXINWORKSHOP/s/flfmc9do2按照这个操作进行创建一个应用&#xff1a; 代码示例 token获取 # 填充API Key与Secret Key import requests import jsondef ma…

blender的下载安装和配置中文环境

引言 在3D建模和动画设计领域&#xff0c;Blender 作为一款强大且免费的开源软件&#xff0c;一直以优秀的性能和对众多技术的支持赢得了大批用户的喜爱。然而&#xff0c;对于刚接触这款软件的用户而言&#xff0c;其安装和配置过程可能会带来一定困扰&#xff0c;尤其是在设…

【redis】创建集群

这里介绍的是创建redis集群的方式&#xff0c;一种是通过create-cluster配置文件创建部署在一个物理机上的伪集群&#xff0c;一种是先在不同物理机启动单体redis&#xff0c;然后通过命令行使这些redis加入集群的方式。 一&#xff0c;通过配置文件创建伪集群 进入redis源码…