当前位置: 首页 > news >正文

桥接模式:解耦抽象与实现,实现灵活多变的扩展结构

文章目录

  • 一、引言
  • 二、应用场景与技术背景
  • 三、模式定义与实现
  • 四、实例详解
  • 五、优缺点分析
  • 总结:

一、引言

​ 桥接模式是一种结构型设计模式,它将抽象部分与它的实现部分分离,使它们可以独立变化。这种模式通过创建一个抽象层和实现层的结构,并使用组合而非继承来关联这两层,从而使得系统在面对多维度变化时,能够保持较低的耦合度,支持灵活扩展。

二、应用场景与技术背景

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

  1. 系统需要在多个维度上进行扩展,而这些维度的变化是相互独立的。
  2. 不希望使用继承来实现组件间的组合,因为这会导致类爆炸或过度耦合。

例如,在图形用户界面(GUI)库中,窗口有多种外观(如Windows风格、Mac风格),同时又有多种操作(如打开、关闭、最大化等)。桥接模式可以帮助我们将窗口外观和窗口操作这两个独立变化的维度进行解耦,让每种外观都能轻松搭配不同的操作实现。

三、模式定义与实现

桥接模式的核心组成部分包括:

在这里插入图片描述

  1. Abstraction(抽象化角色):定义抽象接口,维持一个指向Implementor对象的引用。
  2. RefinedAbstraction(具体抽象化角色):是Abstraction接口的一个实现,负责调用Implementor对象的方法并提供额外的功能。
  3. Implementor(实现化角色):定义实现化角色的接口,供Abstraction角色调用。
  4. ConcreteImplementor(具体实现化角色):实现了Implementor接口,提供了具体的实现。

四、实例详解

以打印机系统为例,品牌属于抽象实现,彩色打印、黑白打印 属于具体实现。

  1. 定义抽象化角色(Abstraction):首先创建一个表示打印机的抽象类Printer,该类包含一个指向打印技术实现对象的引用,并声明了print()方法。
public abstract class Printer {protected PrintTechnology technology;public void setPrintTechnology(PrintTechnology technology) {this.technology = technology;}// 抽象方法,由子类具体实现public abstract void print();
}
  1. 定义具体抽象化角色(Refined Abstraction):创建具体的打印机品牌如HPPrinter作为Printer的子类,它实现了print()方法,在调用打印功能时,会委托给关联的打印技术对象执行实际打印操作。
public class HPPrinter extends Printer {@Overridepublic void print() {System.out.println("HP 打印机开始工作");technology.print(); // 调用实现化角色的方法}
}
  1. 定义实现化角色接口(Implementor):创建一个表示打印技术的接口PrintTechnology,声明了print()方法,为各种不同的打印技术提供统一的接口。
public interface PrintTechnology {void print();
}
  1. 定义具体实现化角色(Concrete Implementor):分别创建两种具体的打印技术实现类,如BlackAndWhitePrintTechnologyColorPrintTechnology,它们都实现了PrintTechnology接口,提供了黑白打印和彩色打印的具体实现。
public class BlackAndWhitePrintTechnology implements PrintTechnology {@Overridepublic void print() {System.out.println("正在进行黑白打印...");}
}public class ColorPrintTechnology implements PrintTechnology {@Overridepublic void print() {System.out.println("正在进行彩色打印...");}
}
  1. 应用端使用:在应用程序中,根据需求动态组合不同的打印机品牌与打印技术。例如,可以创建一个HP品牌的打印机并设置其打印技术为黑白或彩色。
public class BridgePatternDemo {public static void main(String[] args) {Printer hpPrinter = new HPPrinter();// 设置打印技术为黑白打印hpPrinter.setPrintTechnology(new BlackAndWhitePrintTechnology());hpPrinter.print(); // 输出:HP 打印机开始工作\n正在进行黑白打印...System.out.println("===================");// 更改为彩色打印技术hpPrinter.setPrintTechnology(new ColorPrintTechnology());hpPrinter.print(); // 输出:HP 打印机开始工作\n正在进行彩色打印...}
}

测试结果

在这里插入图片描述

​ 通过以上步骤,桥接模式成功地将打印机的品牌(抽象化角色)与其支持的打印技术(实现化角色)解耦合,使得二者可以独立扩展而互不影响。在实际运行时,可以根据需要灵活配置打印机的品牌和打印技术,实现不同维度的组合变化。

五、优缺点分析

优点:

  1. 降低耦合:通过将抽象与实现分离,消除了抽象与实现之间的静态绑定关系,使得两者可以独立改变而不影响对方。
  2. 提高灵活性:新增或修改抽象化角色和实现化角色的子类时,不会对其他子类造成影响,增强了系统的可扩展性。

潜在挑战:

  1. 复杂性增加:引入了更多的类和层次结构,可能增加理解与维护成本。
  2. 过度设计风险:如果需求中不存在独立变化的维度,强行使用桥接模式可能导致设计过于复杂。

总结:

​ 桥接模式通过分离抽象与实现,为系统提供了更加灵活的设计结构,使得系统可以在多个维度上自由扩展。在实际应用中,合理运用桥接模式能有效解决因继承带来的紧耦合问题,提升代码的复用性和可维护性,尤其适用于那些需要应对多维度变化需求的软件设计。然而,也应注意避免在简单系统中过度设计,确保模式的应用符合实际需求和场景特点。

相关文章:

桥接模式:解耦抽象与实现,实现灵活多变的扩展结构

文章目录 一、引言二、应用场景与技术背景三、模式定义与实现四、实例详解五、优缺点分析总结: 一、引言 ​ 桥接模式是一种结构型设计模式,它将抽象部分与它的实现部分分离,使它们可以独立变化。这种模式通过创建一个抽象层和实现层的结构&…...

HUAWEI Programming Contest 2024(AtCoder Beginner Contest 342)

D - Square Pair 题目大意 给一长为的数组,问有多少对,两者相乘为非负整数完全平方数 解题思路 一个数除以其能整除的最大的完全平方数,看前面有多少个与其余数相同的数,两者乘积满足条件(已经是完全平方数的部分无…...

Heap sorting

堆排序比较特殊&#xff0c;采用数组表示堆。 先将数组表示成大根堆或者小根堆。然后从堆中依次取根&#xff0c;最后形成有序序列。 #include<bits/stdc.h> using namespace std;const int N 1e5 10; int a[N];void bigheap(int* a, int start, int len) {if(start …...

开源模型应用落地-qwen2模型小试-入门篇(六)

一、前言 经过前五篇“qwen模型小试”文章的学习,我们已经熟练掌握qwen大模型的使用。然而,就在前几天开源社区又发布了qwen1.5版本,它是qwen2模型的测试版本。在基于transformers的使用方式上有较大的调整,现在,我们赶紧跟上脚步,去体验一下新版本模型的推理质量。 二、…...

c#程序,oracle使用Devart驱动解决第第三方库是us7ascii,数据乱码的问题

最近做项目&#xff0c;要跟对方系统的库进行读写&#xff0c;结果发现对方采用的是oracle的us7ascii编码&#xff0c;我们系统默认采用的是ZHS16GBK&#xff0c;导致我们客户端读取和写入对方库的数据都是乱码&#xff0c;搜索网上&#xff0c;发现需要采用独立的oracle驱动去…...

代码随想录算法训练营第四一天 | 背包问题

目录 背包问题01背包二维dp数组01背包一维 dp 数组&#xff08;滚动数组&#xff09;分割等和子集 LeetCode 背包问题 01背包 有n件物品和一个最多能背重量为 w 的背包&#xff0c;第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#x…...

AIDL的工作原理与使用示例 跨进程通信 远程方法调用RPC

AIDL的介绍与使用 AIDL&#xff08;Android Interface Definition Language&#xff09;是Android中用于定义客户端和服务端之间通信接口的一种接口定义语言。它允许你定义客户端和服务的通信协议&#xff0c;用于在不同的进程间或同一进程的不同组件间进行数据传递。AIDL通过…...

K8S部署Java项目 pod报错 logs日志内容:no main manifest attribute, in app.jar

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

SQL实现模糊查询的四种方法总结

目录 一、一般模糊查询 二、利用通配符查询 1. _ 表示任意的单个字符 2. % 表示匹配任意多个任意字符 3. [ ]表示筛选范围 4. 查询包含通配符的字符串 一、一般模糊查询 1. 单条件查询 //查询所有姓名包含“张”的记录select * from student where name like 张 2. 多条…...

爬虫基本库的使用(urllib库的详细解析)

学习爬虫&#xff0c;其基本的操作便是模拟浏览器向服务器发出请求&#xff0c;那么我们需要从哪个地方做起呢?请求需要我们自己构造吗? 我们需要关心请求这个数据结构怎么实现吗? 需要了解 HTTP、TCP、IP层的网络传输通信吗? 需要知道服务器如何响应以及响应的原理吗? 可…...

【PyQt5桌面应用开发】3.Qt Designer快速入门(控件详解)

一、Qt Designer简介 Qt Designer是PyQt程序UI界面的实现工具&#xff0c;可以帮助我们快速开发 PyQt 程序的速度。它生成的 UI 界面是一个后缀为 .ui 的文件&#xff0c;可以通过 pyiuc 转换为 .py 文件。 Qt Designer工具使用简单&#xff0c;可以通过拖拽和点击完成复杂界面…...

react useMemo 用法

1&#xff0c;useCallback 的功能完全可以由 useMemo 所取代&#xff0c;如果你想通过使用 useMemo 返回一个记忆函数也是完全可以的。 usecallback(fn,inputs)is equivalent to useMemo(()> fn, inputs). 区别是:useCallback不会执行第一个参数函数&#xff0c;而是将它返…...

python学习笔记 - 标准库函数

概述 为了方便程序员快速编写Python脚本程序&#xff0c;Python提供了很多好用的功能模块&#xff0c;它们内置于Python系统&#xff0c;也称为内置函数(Built-in Functions&#xff0c;BlF)&#xff0c;Python 内置函数是 Python 解释器提供的一组函数&#xff0c;无需额外导…...

校招失败后,在小公司熬了 2 年终于进了字节跳动,竭尽全力....

其实两年前校招的时候就往字节投了一次简历&#xff0c;结果很明显凉了&#xff0c;随后这个理想就被暂时放下了&#xff0c;但是这个种子一直埋在心里这两年除了工作以外&#xff0c;也会坚持写博客&#xff0c;也因此结识了很多优秀的小伙伴&#xff0c;从他们身上学到了特别…...

PYTHON-使用正则表达式进行模式匹配

目录 Python 正则表达式Finding Patterns of Text Without Regular ExpressionsFinding Patterns of Text with Regular ExpressionsCreating Regex ObjectsMatching Regex ObjectsReview of Regular Expression MatchingMore Pattern Matching with Regular ExpressionsGroupi…...

Fiddler工具 — 19.Fiddler抓包HTTPS请求(二)

5、查看证书是否安装成功 方式一&#xff1a; 点击Tools菜单 —> Options... —> HTTPS —> Actions 选择第三项&#xff1a;Open Windows Certificate Manager打开Windows证书管理器。 打开Windows证书管理器&#xff0c;选择操作—>查看证书&#xff0c;在搜索…...

架构设计:流式处理与实时计算

引言 随着大数据技术的不断发展&#xff0c;流式处理和实时计算在各行各业中变得越来越重要。那么什么是流式处理呢&#xff1f;我们又该怎么使用它&#xff1f;流式处理允许我们对数据流进行实时分析和处理&#xff0c;而实时计算则使我们能够以低延迟和高吞吐量处理数据。本…...

Linux系统安装zookeeper

Linux安装zookeeper 安装zookeeper之前需要安装jdk&#xff0c;确认jdk环境没问题之后再开始安装zookeeper 下载zookeeper压缩包&#xff0c;官方下载地址&#xff1a;Apache Download Mirrors 将zookeeper压缩包拷贝到Linux并解压 # (-C 路径)可以解压到指定路径 tar -zxv…...

【前端素材】推荐优质后台管理系统Modernize平台模板(附源码)

一、需求分析 后台管理系统是一种用于管理和控制网站、应用程序或系统后台操作的软件工具&#xff0c;通常由授权用户&#xff08;如管理员、编辑人员等&#xff09;使用。它提供了一种用户友好的方式来管理网站或应用程序的内容、用户、数据等方面的操作&#xff0c;并且通常…...

二、Vue组件化编程

2、Vue组件化编程 2.1 非单文件组件 <div id"root"><school></school><hr><student></student> </div> <script type"text/javascript">//创建 school 组件const school Vue.extend({template: <div&…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...