设计模式-桥接模式(Bridge)

2023-11-10

前言

桥接模式(Bridge Pattern)是一种结构型设计模式,用于将抽象部分和实现部分分离,使它们可以独立地变化。这种分离允许你将一个类的功能层次结构(抽象)与另一个类的实现层次结构(实现)分开,从而在不同层次上进行修改和扩展。在本篇博客中,我们将详细介绍桥接模式的概念,然后提供一个Java代码示例来演示如何实现它。

一、桥接模式的概念

桥接模式的核心思想是将一个类的抽象部分与其实现部分分离开来,使它们可以独立地变化。在桥接模式中,抽象部分包括一个抽象类(或接口),它定义了抽象方法,而实现部分包括具体的实现类,它实现了抽象类中的方法。

桥接模式的结构包括以下要素:

  1. 抽象部分(Abstraction):定义抽象类(或接口),并包含一个对实现部分的引用。抽象部分定义了抽象方法,描述了客户端调用的接口。

  2. 扩展抽象部分(Refined Abstraction):扩展抽象部分,可以添加更多的方法或属性,对抽象部分进行更多的定制。

  3. 实现部分(Implementor):定义实现部分的接口,通常包括抽象方法。实现部分提供了具体实现,可以有多个不同的实现类。

  4. 具体实现部分(Concrete Implementor):实现实现部分的具体类,实现了实现部分的接口。

二、桥接模式的实现

让我们通过一个简单的示例来演示桥接模式的实现。我们将创建一个图形绘制应用程序,其中包括抽象图形和实际绘制引擎的桥接。

首先,我们定义抽象图形类 Shape 和绘制引擎接口 DrawingAPI

// 抽象图形类
abstract class Shape {
    protected DrawingAPI drawingAPI;

    protected Shape(DrawingAPI drawingAPI) {
        this.drawingAPI = drawingAPI;
    }

    public abstract void draw();
}

// 绘制引擎接口
interface DrawingAPI {
    void drawCircle(int x, int y, int radius);
}

然后,我们创建具体的图形类 Circle 和实现引擎类 DrawingAPI1

// 具体图形类
class Circle extends Shape {
    private int x, y, radius;

    public Circle(int x, int y, int radius, DrawingAPI drawingAPI) {
        super(drawingAPI);
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    public void draw() {
        drawingAPI.drawCircle(x, y, radius);
    }
}

// 实现引擎类 1
class DrawingAPI1 implements DrawingAPI {
    public void drawCircle(int x, int y, int radius) {
        System.out.printf("API1.circle at %d:%d radius %d%n", x, y, radius);
    }
}

接下来,我们创建另一个实现引擎类 DrawingAPI2

// 实现引擎类 2
class DrawingAPI2 implements DrawingAPI {
    public void drawCircle(int x, int y, int radius) {
        System.out.printf("API2.circle at %d:%d radius %d%n", x, y, radius);
    }
}

最后,我们编写客户端代码来测试桥接模式:

public class BridgePatternDemo {
    public static void main(String[] args) {
        DrawingAPI api1 = new DrawingAPI1();
        DrawingAPI api2 = new DrawingAPI2();

        Shape circle1 = new Circle(1, 2, 3, api1);
        Shape circle2 = new Circle(5, 7, 11, api2);

        circle1.draw();
        circle2.draw();
    }
}

在这个示例中,我们创建了两个不同的绘制引擎 DrawingAPI1DrawingAPI2,以及两个不同的圆形图形 `Circle

三、桥接模式的优缺点

桥接模式(Bridge Pattern)是一种有助于将抽象部分和实现部分分离的设计模式,它有一些明显的优点和一些潜在的缺点。让我们首先讨论一下桥接模式的优点:

1、优点:

  1. 分离抽象和实现:桥接模式通过将抽象部分和实现部分分离,使它们可以独立变化。这提高了系统的灵活性,允许你对它们进行独立的扩展和修改。

  2. 可扩展性:你可以轻松地扩展抽象部分和实现部分,而不必修改已有的代码。这使得你可以根据需要添加新的抽象或实现类,而无需改变现有代码。

  3. 可维护性:分离抽象和实现部分使代码更清晰,易于理解和维护。每个部分都有自己的接口,便于理解其功能和责任。

  4. 多维度变化:桥接模式允许多维度的变化,既可以扩展抽象部分,也可以扩展实现部分。这种组合可以产生多样化的对象组合,使得系统更加灵活。

  5. 隐藏细节:客户端不需要了解实现细节,只需与抽象接口交互。这有助于隐藏复杂性和细节,使客户端代码更简洁。

2、缺点:

  1. 增加复杂性:桥接模式引入了抽象部分和实现部分之间的间接性,可能会增加系统的复杂性。对于简单的情况,使用桥接模式可能会显得过于繁琐。

  2. 适用性限制:桥接模式主要用于处理抽象和实现之间的多维度变化。对于单一维度的变化,可能会显得过于繁重。

  3. 增加类的数量:桥接模式通常需要创建多个抽象类和实现类,这可能会导致类的数量增加。在小型项目中,这可能不是一个问题,但在大型项目中需要谨慎考虑。

  4. 设计的抽象程度:确定抽象和实现的划分和接口设计需要一定的经验和抽象能力。不恰当的设计可能导致模式失效或增加不必要的复杂性。

总的来说,桥接模式是一种有助于解决多维度变化的设计模式,它提供了灵活性和可维护性,但也需要权衡复杂性和适用性。在设计中,应根据具体的需求和情况来决定是否使用桥接模式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式-桥接模式(Bridge) 的相关文章

  • docker-compose:容器之间的 Redis 连接被拒绝

    我正在尝试设置一个 docker compose 文件 该文件旨在替换运行多个进程 RQ 工作线程 RQ 仪表板和 Flask 应用程序 的单个 Docker 容器解决方案导师 http supervisord org 主机系统是 Debi
  • 在 sympy 绘图中,如何获得具有固定纵横比的绘图?

    如果我用这个片段画一个圆 from sympy import x y symbols x y p1 plot implicit Eq x 2 y 2 1 aspect ratio 1 1 我会得到一个像这样的图形窗口 现在长宽比不是我所期望
  • goJS 下拉菜单删除项目

    我有简单的 python Flask goJS 图形应用程序 如下所示 节点和链接文本的源是从应用程序的后端加载的 我将它们设置为model modelData像这样的部分 var graphDataString JSON parse di
  • 在Linux中的端口80上运行flask[重复]

    这个问题在这里已经有答案了 也许以前有过这个问题的答案 所以请重定向我 如果是这样的话 我正在考虑在端口 80 上运行 Flask 所以我检查了是否有任何东西正在使用端口 80 因为事实证明端口 80 没有运行 所以当我输入以下内容时 if
  • python 打开相对文件夹中所有以.txt结尾的文件

    我需要打开并解析文件夹中的所有文件 但我必须使用相对路径 类似于 input files 我知道在 JavaScript 中你可以使用 path 库来解决这个问题 我怎样才能在Python中做到这一点 这样您就可以获得路径中的文件列表作为列
  • 使用 OpenCV 进行图像模糊检测

    我正在研究图像的模糊检测 我已经用过拉普拉斯方法的方差在 OpenCV 中 img cv2 imread imgPath gray cv2 cvtColor img cv2 COLOR BGR2GRAY value cv2 Laplacia
  • gcloud app deploy:此部署有太多文件

    当我尝试通过 gcloud 部署我的 GAE 应用程序时 出现以下错误 Updating service default failed ERROR gcloud app deploy Error Response 400 This depl
  • 如何逐行替换(更新)文件中的文本

    我试图通过读取每一行 测试它 然后写入是否需要更新来替换文本文件中的文本 我不想保存为新文件 因为我的脚本已经先备份文件并对备份进行操作 这是我到目前为止所拥有的 我从 os walk 获取路径 并且保证 pathmatch var 正确返
  • 如何让 Discord 机器人显示“机器人正在输入...”状态?

    所以如果我有一个像这样的长命令 bot command pass context True async def longCommand ctx typing status sleep 10 bot say Done 不幸的是 在文档或此处没
  • 桨在移动时留下痕迹(Pygame Pong 游戏)[重复]

    这个问题在这里已经有答案了 我的游戏中的球拍有问题 每次我试图移动它时 桨都会留下一条 痕迹 我想这是因为我的代码没有删除旧位置的前一个桨 如果是的话怎么删除之前的呢 我应该使用blit Code import pygame sys ran
  • 即使使用标头和 Session 对象,Python requests.get 也会失败并出现 403 禁止

    我正在发出 GET 请求来获取 JSON 它在任何设备上的任何浏览器中都可以正常工作 但不能通过 python 请求 url https angel co autocomplete new tags params query sci tag
  • 使用字体模块的 Tkinter 代码无法从命令行运行?

    我有使用 tkinter 的代码 我可以从 IDLE 运行得很好 但会引发异常AttributeError module object has no attribute font 当它从命令行运行时 其他 tkinter 程序工作正常 但任
  • Python 宏:用例?

    如果 Python 有一个类似于 Lisp Scheme 的宏工具 比如元Python https code google com p metapython 你会如何使用它 如果您是一名 Lisp Scheme 程序员 您会使用宏来做什么
  • 从 Cython 代码生成 SIMD 指令

    我需要概述在高性能数字代码中使用 Cython 可以获得的性能 我感兴趣的事情之一是找出优化的 C 编译器是否可以对 Cython 生成的代码进行矢量化 所以我决定写下面的小例子 import numpy as np cimport num
  • Python 柯里化任意数量的变量

    我正在尝试使用柯里化在 Python 中进行简单的函数添加 我找到了这个咖喱装饰器here https gist github com JulienPalard 021f1c7332507d6a494b def curry func def
  • 如何在Python中一次比较二维数组的2列与另一个数组的列

    我有两个字符串数组 每个数组有三列 我想比较两个二维数组的前两列 有 3 列和 4000 行 如果它们匹配 那么我需要那些匹配的值 但是我的代码不起作用 这是一个示例 array1 1stcolumn 2ndColumn 3rdColumn
  • 按键合并的两个字典的值的并集

    我有两本词典 d1 a x y b k l d2 a m n c p r 如何合并这两个字典以获得这样的结果 d3 a x y m n b k l c p r 当字典的值是简单类型 如 int 或 str 时 这有效 d3 dict i a
  • 如何找到 JAR:/home/hadoop/contrib/streaming/hadoop-streaming.jar

    我正在练习有关 Amazon EMR 的复数视角视频教程 我被困住了 因为我收到此错误而无法继续 Not a valid JAR home hadoop contrib streaming hadoop streaming jar 请注意
  • 如何从集合中检索元素而不删除它?

    假设如下 gt gt gt s set 1 2 3 我如何获得一个值 任何值 s不做s pop 我想将该项目保留在集合中 直到我确定可以删除它 这只有在异步调用另一个主机之后才能确定 又快又脏 gt gt gt elem s pop gt
  • 根据键的重复值从列表中删除字典

    我是Python新手 假设我有以下字典列表 mydictList a 1 b 2 c 3 a 2 b 2 c 4 a 2 b 3 c 4 从上面的列表中 我想删除具有相同键 b 值的字典 所以结果列表应该是 mydictList a 1 b

随机推荐

  • Java:多线程概述与创建方式

    文章目录 Java 多线程概述与创建方式 进程和线程 并发与并行 多线程的优势 线程的创建和启动 继承Thread类 start 和run 实现Runnable接口 实现Callable接口 创建方式的区别 Java 多线程概述与创建方式
  • 垃圾回收机制

    垃圾回收机制 垃圾回收一般分为两步 分别是 1 发现无用的对象 2 回收无用对象站用的内存空间 垃圾回收常用的两种算法 1 引用计数法 优点是算法简单 缺点是 循环引用大额无用对象无法识别 2 引用可达法 根搜索算法 堆内存划分成 年轻代
  • docker---runlike查看容器run命令详情

    文章目录 一 安装 二 使用 一 安装 一般情况下linux系统中都内置了pip3 没有的话先手动安装下 yum install python3 pip 安装runlike pip3 install runlike 二 使用 runlike
  • html为什么图片有的显示不出来,网页显示不出图片怎么办 6种常见的解决方案详解...

    我们上网的时候 可能因为种种原因导致网页显示不出图片 那么网页显示不出图片怎么办呢 有哪些解决的方法 接下来小编就简单的给大家介绍一下网页显示不出图片怎么办 网页显示不出图片怎么办 1 网速问题 网页显示不出图片有可能是因为电脑的网速比较慢
  • 【每日练习】从两个数字数组里生成最小数字

    题目描述 给你两个只包含 1 到 9 之间数字的数组 nums1 和 nums2 每个数组中的元素 互不相同 请你返回最小的数字 两个数组都至少包含这个数字的某个数位 示例 示例 1 输入 nums1 4 1 3 nums2 5 7 输出
  • Seaweedfs部署

    软件下载地址 https github com seaweedfs seaweedfs releases 创建工作目录 mkdir wkspace contribs seaweedfs 将下载的组件包放到此目录下 解压组件包 tar xvf
  • tar打包隐藏文件

    默认情况下 tar打包当前目录是不会包含隐藏文件的 但奇葩的是 他会包含当前目录子目录下的隐藏文件 bm6j80 aaa find aa aa cc bb bm6j80 aaa tar cvf test tar aa aa cc bb bm
  • 数组对象深拷贝

    数组对象深拷贝再研究 常见的深层数组对象拷贝方式有 concat 解构 JSON解析 函数递归等 concat var ary2 ary1 concat es6解构 var ary2 ary1 var ary2 ary1 JSON解析 va
  • 6行代码最简单的VB6标准DLL工程

    vb6可以做标准DLL方法很简单 利用了一个微软未公开的方法 不需要LINK工具 牛人还可以把DLL加上多线程等功能 再加上VB头初始化 VB6标准DLL就无所不能了 VB6做的控件 又是标准DLL 又是COM对象 还可以单文件运行 exe
  • Spring3学习笔记之(spring core 之DI(Bean作用域))

    Bean的作用域 什么是作用域呢 即 scope 在面向对象程序设计中一般指对象或变量之间的可见范围 而在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围 Spring提供 singleton 和 protot
  • 深度强化学习系列: “奖励函数”的设计和设置(reward shaping)

    概述 前面已经讲了好几篇关于强化学习的概述 算法 DPG gt DDPG 也包括对环境OpenAI gym的安装 baseline算法的运行和填坑 虽然讲了这么多 算法也能够正常运行还取得不错的效果 但是一直以来忽略了一个非常重要的话题 那
  • 【100%通过率 】华为O机试C++/java/python【箱子之字形摆放】 2022 Q4 A卷

    华为OD机试 题目列表 2023Q1 点这里 2023华为OD机试 刷题指南 点这里 题目描述 有一批箱子 形式为字符串 设为str 要求将这批箱子按从上到下以之字形的顺序摆放在宽度为 n 的空地 请输出箱子的摆放位置 例如 箱子ABCDE
  • Yolov5的安装配置及实现目标检测

    本文内容 本文主要介绍anaconda下yolov5的安装配置方法 以及如何实现目标检测 目录 一 yolov5的下载安装 一 环境配置 二 下载yolov5 二 yolov5测试 一 图片测试 二 视频测试 三 调用手机摄像头实现实时检测
  • 如何使用 Docker 部署 FreeGPT-WebUI:一个简单的教程

    目录 1 FreeGPT WebUI 项目简介 2 安装 Docker 3 从 Docker Hub 拉取 FreeGPT WebUI 镜像 4 使用 Docker 运行 FreeGPT WebUI 应用程序 5 访问 FreeGPT We
  • python菜鸟学习Day1(数据类型)

    第一节 数据类型 int 整型 python2中有int long python3中只有int float 浮点型 string 字符串型 bool 布尔型 变量命名 字母 数字 下划线 数据不能开头 大小写敏感 不能和系统关键字 函数名
  • [2020.1.19][udev] 金步国udev

    金步国index里有4条udev相关的 1 udevadm 2 udev 3 systemd udevd service udevd守护进程 4 udev conf 1 udevadm 1 udevadm info options devp
  • linux 安装nginx+php +mysql 安装

    安装make make命令是GNU的工程化编译工具 用于编译众多相互关联的源代码问价 以实现工程化的管理 提高开发效率 安装PCRE库 g wget yum y install gcc gcc c wget pcre pcre devel
  • IP 地址解析与子网划分教程

    数据来源 一 简单局域网的构成 局域网 一般称为内网 简单局域网的构成 交换机 网线 PC 其他IT终端 交换机 用来组建内网的局域网的设备 交换机并不能让电脑上网 需要通过路由器 路由器 路由器可以为局域网自动分配IP和虚拟拨号 电脑需要
  • 高精度减法详解

    高精度减法详解 建议先学习高精度加法 高精度加法详解 当减数 被减数 差特别大时 大到无法用long long来存储 外面就需要使用高精度算法解决 算法基本思想 存储就是和加法差不多 都是用数组解决问题 计算就使用小学竖式计算即可 算法描述
  • 设计模式-桥接模式(Bridge)

    文章目录 前言 一 桥接模式的概念 二 桥接模式的实现 三 桥接模式的优缺点 1 优点 2 缺点 前言 桥接模式 Bridge Pattern 是一种结构型设计模式 用于将抽象部分和实现部分分离 使它们可以独立地变化 这种分离允许你将一个类