设计模式之桥接模式解析

news2024/9/23 22:44:11
桥接模式
1)概述
1.定义

桥接模式(Bridge Pattern) 将抽象部分与它的实现部分分离,使它们都可以独立地变化。

2.作用

如果系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展。

3.实现

与多层继承方案不同,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,该关联关系类似一条连接两个独立继承结构的桥,故名桥接模式。

4.结构图

在这里插入图片描述

5.角色介绍

●Abstraction(抽象类):用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义了一个Implementor(实现类接口)类型的对象并可以维护该对象,它与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。

●RefinedAbstraction(扩充抽象类):扩充由Abstraction定义的接口,通常情况下它不再是抽象类而是具体类,它实现了在Abstraction中声明的抽象业务方法,在RefinedAbstraction中可以调用在Implementor中定义的业务方法。

●Implementor(实现类接口):Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多更复杂的操作。Implementor接口对这些基本操作进行了声明,而具体实现交给其子类,通过关联关系,在Abstraction中不仅拥有自己的方法,还可以调用到Implementor中定义的方法,使用关联关系来替代继承关系。

●ConcreteImplementor(具体实现类):具体实现Implementor接口,在不同的ConcreteImplementor中提供基本操作的不同实现,在程序运行时,ConcreteImplementor对象将替换其父类对象,提供给抽象类具体的业务操作方法。

2)案例-完整解决方案
1.结构图

在这里插入图片描述

Image充当抽象类,其子类JPGImage、PNGImage、BMPImage和GIFImage充当扩充抽象类;ImageImp充当实现类接口,其子类WindowsImp、LinuxImp和UnixImp充当具体实现类。

2.代码实现

抽象类

//抽象图像类:抽象类
abstract class Image {
    protected ImageImp imp;

    public void setImageImp(ImageImp imp) {
        this.imp = imp;
    }

    public abstract void parseFile(String fileName);
}

扩充抽象类

//JPG格式图像:扩充抽象类
public class JPGImage extends Image {
    public void parseFile(String fileName) {
        //模拟解析JPG文件并获得一个像素矩阵对象m;
        imp.doPaint("图片为");
        System.out.println(fileName + ",格式为JPG。");
    }
}

//PNG格式图像:扩充抽象类
public class PngImage extends Image {
    public void parseFile(String fileName) {
        //模拟解析JPG文件并获得一个像素矩阵对象m;
        imp.doPaint("图片为");
        System.out.println(fileName + ",格式为Png。");
    }
}

实现类接口

//抽象操作系统实现类:实现类接口
interface ImageImp {
    public void doPaint(String text);
}

接口实现类

//Mac操作系统实现类:具体实现类
public class MacImp implements ImageImp {
    public void doPaint(String text) {
        //调用Windows系统的绘制函数绘制像素矩阵
        System.out.print("在Mac操作系统中显示图像:"+text);
    }
}

//Windows操作系统实现类:具体实现类
public class WindowsImp implements ImageImp {
    public void doPaint(String text) {
        //调用Windows系统的绘制函数绘制像素矩阵
        System.out.print("在Windows操作系统中显示图像:"+text);
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        Image image = new JPGImage();
        ImageImp imp = new MacImp();
        image.setImageImp(imp);
        image.parseFile("小龙女");
    }
}
3)适配器模式与桥接模式联用
1.概述

桥接模式用于系统的初步设计,对于存在两个独立变化维度的类可以将其分为抽象化和实现化两个角色,使它们可以分别进行变化。

在初步设计完成之后,当发现系统与已有类无法协同工作时,可以采用适配器模式。

2.案例

a)背景

在某系统的报表处理模块中,需要将报表显示和数据采集分开,系统可以有多种报表显示方式也可以有多种数据采集方式,如可以从文本文件中读取数据,也可以从数据库中读取数据,还可以从Excel文件中获取数据。

如果需要从Excel文件中获取数据,则需要调用与Excel相关的API,而这个API是现有系统所不具备的,该API由厂商提供,需要使用适配器模式和桥接模式设计该模块。

b)方案

在设计过程中,由于存在报表显示和数据采集两个独立变化的维度,因此可以使用桥接模式进行初步设计;

为了使用Excel相关的API来进行数据采集则需要使用适配器模式,系统的完整设计中需要将两个模式联用。

在这里插入图片描述

4)总结
1.优点
  • 分离抽象接口及其实现部分,桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。

  • 桥接模式可以取代多层继承方案。

  • 桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合“开闭原则”。

2.缺点
  • 桥接模式的使用会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程。

  • 桥接模式要求正确识别出两个独立变化的维度,因此其使用范围具有一定的局限性。

3.适用场景
  • 如果一个系统需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。

  • “抽象部分”和“实现部分”可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。

  • 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。

  • 对于那些不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。

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

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

相关文章

Android开发简易登录界面

title: Android开发第四天 search: 2024-03-22 tags: Android开发 Android开发简易登录界面 文章目录 Android开发简易登录界面一、定义style样式二、完成 activity_main.xml 界面具体设计三、代码简述 背景 :在初学 android 开发的时候,为了尽量熟悉学…

看漫画学Python:有趣好玩

书籍介绍 Python是一门既简单又强大的编程语言,被广泛应用于数据分析、大数据、网络爬虫、自动化运维、科学计算和人工智能等领域。Python也越来越重要,成为国家计算机等级考试科目,某些中小学也开设了Python编程课程。本书秉承有趣、有料、…

js实现操作浏览器返回时,页面有弹窗则关闭弹窗而不实际返回

关于popstate、pushState参考:HTML5的popstate、pushState、replaceState如何玩转浏览器历史记录-CSDN博客文章浏览阅读1.3w次,点赞8次,收藏30次。一、popstate用来做什么的?简而言之就是HTML5新增的用来控制浏览器历史记录的api。二、过去如何操纵浏览器历史记录?window.…

自定义组件学习

效果 自定义组件模块 <template> <div class"flex-1"><div :style"{width: wrapWidth}" class"flex-margin mb8"><OprateSteps :operateHtml"operateHtml" /></div><ul class"datacollect-…

Ftrans安全数据摆渡系统 构建便捷的内外网数据交换通道

安全数据摆渡系统是一种设计用于解决内外网环境下&#xff0c;数据传输、管理、共享问题的安全系统&#xff0c;通过加密、访问控制等策略&#xff0c;提供安全可靠的数据传输和共享服务&#xff0c;尤其适用于对网络安全建设要求高的行业&#xff0c;比如研发型企业、党政机构…

异步引入组件

defineAsyncComponent 函数&#xff1a;用于异步引入组件。 Suspense 标签&#xff1a;异步组件加载时&#xff0c;显示的默认内容。 应用场景&#xff1a;当子组件的数据量较大&#xff0c;导致父组件延迟显示时使用。 语法格式 异步引入组件&#xff1a; import { define…

Java:ArrayList与顺序表

一、线性表 线性表是n个具有相同特征的数据元素的有限序列&#xff0c;它是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表有&#xff1a;顺序表、链表、栈、队列...... 如图&#xff1a;顺序表与链表的区别看了标题的伙伴就应该知道&#xff0c;我们这次要讲解的主…

Java多线程实战-从零手搓一个简易线程池(一)定义任务等待队列

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️本系列源码仓库&#xff1a;多线程并发编程学习的多个代码片段(github) &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正…

router.push是同步还是异步?push.then和子组件onMounted谁先触发?

直接做实验&#xff1a; <el-button type"danger" click"test">toAbout</el-button>// -----const test () >{router.push(about).then((e)>{console.log(then里面, e);}).finally((e)>{console.log(finally里面, e);})console.log…

【Unity3D小功能】Unity3D中实现点击‘文字’出现‘UI面板’

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群&#xff1a;398291828 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 宠粉博主又来了&#xff0c;今天有粉丝问我如何实…

机器学习 - 神经网络分类

什么叫做分类问题&#xff1f; A classification problem involves predicting whether something is one thing or another. Problem typeWhat is it?ExampleBinary classificationTarget can be one of two options, e.g. yes or noPredict whether or not someone has hea…

AXI_Lite协议详解

文章目录 摘要一、AXI_Lite接口全局信号&#xff1a;1、写地址通道&#xff1a;2、写数据通道&#xff1a;3、写响应通道&#xff1a;4、读地址通道&#xff1a;5、读数据通道&#xff1a; 二、仿真波形 摘要 AXI4-lite是AXI4-full的简化版。用于简单、低吞吐量的内存映射通信…

基于CNN-RNN的动态手势识别系统构建与应用

一、引言 随着人机交互技术的不断发展&#xff0c;动态手势识别成为了近年来的研究热点。动态手势识别技术能够识别和理解人类的手势动作&#xff0c;从而实现更自然、更直观的人机交互。本文旨在构建一种基于CNN-RNN的动态手势识别系统&#xff0c;以提高手势识别的准确性和实…

36.基于SpringBoot + Vue实现的前后端分离-高校汉服租赁网站系统(项目 + 论文)

项目介绍 本站是一个B/S模式系统&#xff0c;采用SpringBoot Vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SpringBoot Vue技术的高校汉服租赁网站系统设计与实现管理…

Go第三方框架--gin框架(二)

4. gin框架源码–Engine引擎和压缩前缀树的建立 讲了这么多 到标题4才开始介绍源码&#xff0c;主要原因还是想先在头脑中构建起 一个大体的框架 然后再填肉 这样不容易得脑血栓。标题四主要涉及标题2.3的步骤一 也就是 标题2.3中的 粗线框中的内容 4.1 Engine 引擎的建立 见…

Filter、Listener、AJAX

Filter 概念&#xff1a;Filter 表示过滤器&#xff0c;是JavaWeb三大组件(Servlet、Filter、 Listener)之一。 过滤器可以把对资源的请求拦截下来&#xff0c;从而实现一些特殊的功能。 过滤器一般完成一些通用的操作&#xff0c;比如&#xff1a;权限控制、统一编码处理、敏感…

Mac 装 虚拟机 vmware、centos7等

vmware&#xff1a; https://www.vmware.com/products/fusion.html centos7 清华镜像&#xff1a; 暂时没有官方的 m1 arm架构镜像 centos7 链接: https://pan.baidu.com/s/1oZw1cLyl6Uo3lAD2_FqfEw?pwdzjt4 提取码: zjt4 复制这段内容后打开百度网盘手机App&#xff0c;操…

【Python】Scrapy整合FastAPI实现爬虫API 附大量示例

文章目录 前言1. 网页分析入门1.1 基本原理1.2 Scrapy 原理 2. 创建项目2.1 创建Scrapy项目2.2.1 创建Scrapy项目2.2.2 创建Spider2.2.3 执行Demo 2.2 引入FastAPI 2. 获取Cookie3. 数据建模3.1 Scrapy 数据建模3.2 SQLAlchemy 创建实体类 3. 分析网页3.1 xpath 分析3.2 css 分…

计算机进制转换:二进制、八进制、十进制、十六进制。原码、补码、反码。

一、什么是进制 在生活中&#xff0c;我们通常都是使用阿拉伯数字计数的&#xff0c;也就是10进制&#xff0c;以10为单位&#xff0c;遇10进一&#xff0c;所以是由0&#xff0c;1&#xff0c;2、3、4、5、6、7、8、9组成的&#xff1b;而在计算机中&#xff0c;计算机是无法…

AI工具排行榜:最全工具汇总

如今,人工智能技术正在快速崛起,AI助手、语音识别、机器翻译等工具深深渗透到我们的工作和生活中。这些智能工具极大地提高了我们的工作效率,使我们能更加专注于创造性的任务。 本文将为读者推荐一些实用的AI神器,只要掌握其中一个,就能极大地提升你的工作能力,事半功倍。这些…