桥接模式(Brige)

news2024/12/27 12:21:11

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

Bridge is a structural design pattern that separates the abstract part and the implementation part, 
allowing them to change independently.  

结构设计

桥接模式包含如下角色:
Abstraction:抽象类,抽象部分,提供高层控制逻辑,依赖于完成底层实际工作的实现对象。
RefinedAbstraction:扩充抽象类,提供控制逻辑的变体。 与其父类一样, 它们通过通用实现接口与不同的实现进行交互。
Implementor:实现类接口,实现部分,为所有具体实现声明通用接口。抽象部分仅能通过在这里声明的方法与实现对象交互。抽象部分可以列出和实现部分一样的方法,但是抽象部分通常声明一些复杂行为,这些行为依赖于多种由实现部分声明的原语操作。
ConcreteImplementor:具体实现类,包括特定于平台或场景的代码。
桥接模式类图表示如下:
请添加图片描述

伪代码实现

接下来将使用代码介绍下桥接模式的实现。

// 1、抽象部分,提供高层控制逻辑
public class Abstraction {
    protected Implementor implementor;
    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }
    public void operation() {
        implementor.operationImp();
    }
}

// 2、实现部分,为所有具体实现声明通用接口
public interface Implementor {
    void operationImp();
}

// 4、具体实现类,包括特定于平台或场景的代码
public class RefinedAbstraction extends Abstraction {
    public RefinedAbstraction(Implementor implementor) {
        super(implementor);
    }
    @Override
    public void operation() {
        this.implementor.operationImp();
    }
}
// 5、客户端调用
public class BridgeClient {
    public void test() {
        // (1) 指定抽象部分并绑定具体的实现部分
        Abstraction abstraction1 = new RefinedAbstraction(new ConcreteImplementorA());
        // (2) 调用抽象部分接口
        abstraction1.operation();
    }
}

适用场景

在以下情况可以考虑使用桥接模式:
(1) 如果想要拆分或重组一个具有多重功能的庞杂类(例如需要与多个数据库进行交互的类),可以考虑使用桥接模式。
桥接模式可以将庞杂类拆分为几个类层次结构。 此后, 你可以修改任意一个类层次结构而不会影响到其他类层次结构。 这种方法可以简化代码的维护工作, 并将修改已有代码的风险降到最低。
(2) 如果希望在几个独立维度上扩展一个类, 可以考虑使用桥接模式。
桥接建议将每个维度抽取为独立的类层次。 初始类将相关工作委派给属于对应类层次的对象, 无需自己完成所有工作。
(3) 如果需要在运行时切换不同实现方法, 可以考虑使用桥接模式。
当然并不是说一定要实现这一点, 桥接模式可替换抽象部分中的实现对象, 具体操作就和给成员变量赋新值一样简单。
顺便提一句, 最后一点是很多人混淆桥接模式和策略模式的主要原因。 记住, 设计模式并不仅是一种对类进行组织的方式, 它还能用于沟通意图和解决问题。
(4) 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
(5) 抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
(6) 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
(7) 虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
(8) 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。

优缺点

桥接模式有以下优点:
(1) 符合开闭原则。分离抽象接口及其实现部分。开发者可以单独新增抽象部分和实现部分,它们之间不会相互影响。
(2) 符合单一职责原则。抽象部分专注于处理高层逻辑, 实现部分处理平台细节。
(3) 提高了代码的可扩展性。在抽象部分或实现部分任意扩展一个维度,都不需要修改原有系统。
(4) 提高了代码的透明性。 实现细节对客户透明,可以对用户隐藏实现细节。
(5) 提高了代码的复用性。桥接模式有时类似于多继承方案,但是多继承方案违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差,
而且多继承结构中类的个数非常庞大,桥接模式是比多继承方案更好的解决方法。
但是桥接模式也存在以下缺点:
(1) 代码复杂度上升。比如对高内聚的类使用该模式可能会使代码更加复杂。
(2) 增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
(3) 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。

参考

《设计模式:可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著 李英军, 马晓星 等译
https://refactoringguru.cn/design-patterns/bridge 桥接模式
https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/bridge.html 桥接模式
https://www.cnblogs.com/adamjwh/p/9033548.html 简说设计模式——桥接模式
https://blog.csdn.net/ShuSheng0007/article/details/88370067 秒懂设计模式之桥接模式
https://www.runoob.com/design-pattern/bridge-pattern.html 桥接模式

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

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

相关文章

蓝桥云课ROS机器人旧版实验报告-02架构及概念

项目名称 实验二 ROS[Kinetic/Melodic/Noetic]架构及概念 成绩 内容:机器人操作系统文件系统级、计算图级、社区级、创建功能包并实现功能等 实验记录(70分) 安装一个可用的 build-from-source 包: 在克隆之前&#xff…

Jmeter函数助手(一)随机字符串(RandomString)

一、目标 实现一个请求单次调用,请求体里多个集合中的相同参数(zxqs)值随机从序列{01、02、03、03、04、05、06、07、08}中取 若使用CSV数据文件、用户参数等参数化手段,单次执行请求,请求体里多个集合中的相同参数&a…

生产服务器突然本机无法访问本机IP的端口

生产服务器突然本机无法访问本机IP的端口 一、现象描述 生产服务器突然无法访问自己本机IP地址的端口,通过localhost或者127.0.0.1都可以正常访问 二、问题分析 服务器是搭建在虚拟机上面,起初由于服务器内存不足的原因,导致了服务器故障无…

基于ssm 网上购物系统-计算机毕设 附源码12503

基于SSM网上购物系统 摘 要 近年来,随着移动互联网的快速发展,电子商务越来越受到网民们的欢迎,电子商务对国家经济的发展也起着越来越重要的作用。简单的流程、便捷可靠的支付方式、快捷畅通的物流快递、安全的信息保护都使得电子商务越来越…

Nginx配置与使用

引言 早期的业务都是基于单体节点部署,由于前期访问流量不大,因此单体结构也可满足需求,但随着业务增长,流量也越来越大,那么最终单台服务器受到的访问压力也会逐步增高。时间一长,单台服务器性能无法跟上业…

Spring学习记录----十五、面向切面编程AOP+十六、Spring对事务的支持

十五、面向切面编程AOP IoC使软件组件松耦合。AOP让你能够捕捉系统中经常使用的功能,把它转化成组件。 AOP(Aspect Oriented Programming):面向切面编程,面向方面编程。(AOP是一种编程技术) …

什么是EhCache 缓存

EhCache 缓存-提高检索效率的利器 缓存-官方文档 文档地址: https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache EhCache 缓存 配置文档: https://www.cnblogs.com/zqyanywn/p/10861103.html 基本介绍 EhCache 是一个纯Java 的缓存框架,具有快速、精干等…

GORM 并发执行 Save 更新记录报:Error 1062 (23000)

文章目录 1.Save 简介2.问题3.原因4.小结参考文献 1.Save 简介 先看一下 Save 方法的描述: // Save updates value in database. If value doesnt contain a matching primary key, value is inserted. func (db *DB) Save(value interface{}) (tx *DB)Save 有两个…

lc1109.航班预定统计

暴力解法:按照示例在firsti到lasti遍历,将seati加到每个数上。时间复杂度取决于bookings的长度 一维差分:建立初始数组和差分数组,在差分数组的firsti位置加上seati,差分数组的lasti1位置减去seati(避免影…

偶数科技发布实时湖仓数据平台Skylab 5.3版本

近日, 偶数发布了最新的实时湖仓数据平台 Skylab 5.3 版本。Skylab包含七大产品,分别为云原生分布式数据库 OushuDB、数据分析与应用平台 Kepler、数据资产管理平台 Orbit、自动化机器学习平台 LittleBoy、数据工厂 Wasp、数据开发与调度平台 Flow、系统…

vscode如何包含第三方库

方法1:使用C Extension 在include 的 rapidjson的头文件时,vscode会提示找不到的问题 悬停,点击黄色提示 Edit "includePath" setting Include Path,输入rapidjson的include路径 /Users/xxx/workspaces/rapidjson-1.1.…

服务器出入口IP通俗理解

一、出口IP 这是机房的网络设备(如防火墙)给内网主机生成的一个外网IP,用来保证内网主机能和其他公网主机进行来回通信,通常作为其他接入方的IP白名单使用,一般有几台内网主机就有几个出口IP,出口IP通常和入…

TSINGSEE青犀视频AI算法引擎中台在渣土车智慧管控场景中的应用

一、行业背景 随着社会的发展和人们生活水平的不断进步,大家对环境卫生和空气质量的要求越来越重视。渣土车是建筑垃圾的运输主力,也存在行驶频繁、不合规、不合法的操作,可能对交通安全、环境卫生和城市形象造成影响。比如在施工工地&#x…

Django音乐电台推荐系统【纯干货分享,免费领源码00750】

摘要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流,人类发展的历史正进入一个新时代。在现实运用中,应用软件的工作规…

【云原生】K8S超详细概述

目录 一、Kubernets概述1.1 K8S什么1.2为什么要用K8S 二、Kubernetes 集群架构与组件2.1Master组件Kube-apiserverKube-controller-managerKube-scheduler 2.2 配置存储中心etcd 2.3 Node 组件KubeletKube-Proxydocker 或 rocket 三、 Kubernetes 核心概念3.1Pod3.2Pod 控制器K…

WPF上位机5——C#运算符、特性、反射

C#运算符 按位操作 特性 预定义特性(内置) 自定义特性 通过特性获得数据表列的名称 反射 通过反射创建对象并调用对象的方法

【Vue组件eval方法的使用】

Vue页面中条件可以放在当前vue页面中而无需影响到组件 如 这是我的表格操作列按钮,需求是第四个按钮如果表格当前数据的is_execl字段为0则显示否则隐藏 这种条件判断很频繁 如果像之前一样给一个标识,页面多了就难以维护,而且判断条件如果不…

使用docker部署Wordpress

文章目录 1.创建网络2.创建volume存储3.拉取镜像4.创建mysql容器mysql修改密码 5.创建wordpress容器6.访问localhost:80就可以直接使用啦 1.创建网络 docker network create --subnet172.18.0.0/24 pro-net2.创建volume存储 # mysql 存储 docker volume create volume_mysql…

程序员成长之路心得篇——高效编码诀窍

随着AIGC的飞速发展,程序员越来越能够感受到外界和自己的压力。如何能够在AI蓬勃发展的时代不至于落后,不至于被替代?项目的开发效率起了至关重要的作用。 首先提出几个问题: 如何实现高效编程?高效编程的核心在于哪里&#xff…

无涯教程-Lua - 变量声明

变量的名称可以由字母,数字和下划线字符组成。它必须以字母或下划线开头,由于Lua区分大小写,因此大写和小写字母是不同的。 在Lua中,尽管无涯教程没有变量数据类型,但是根据变量的范围有三种类型。 全局变量(Global) …