【设计模式】第八章:桥接模式详解及应用案例

news2024/11/26 20:33:49

系列文章

【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式


文章目录

  • 系列文章
  • 一、定义
  • 二、角色分类
  • 三、实现方式
    • UML图
    • 需求分析
    • 具体实现
  • 四、应用场景
  • 五、优缺点
    • 优点
    • 缺点


一、定义

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


二、角色分类

抽象化角色(Abstraction)

它是一个抽象类或接口,定义了代表抽象概念的基本操作。通常情况下,抽象化角色会调用实现化的角色从而起到桥接的作用

扩展抽象化角色(Refined Abstraction)

继承或实现抽象化类的子类,可以对抽象类进行扩展,同时还通过实例化对象来调用实例化中具体的方法

实现化角色(Implementor)

一个接口或抽象类,定义了实例化部分的通用接口,并规定了与抽象化角色相对应的具体实现方法

具体实现化角色(Concrete Implementor)

实现了实例化角色中的方法,提供具体的实现逻辑

客户角色(Client)

具体调用方法的角色


三、实现方式

UML图

Image.png

需求分析

假如我们要完成一个绘制图形的功能,其中绘制的图形可以有多个(圆形、矩形等),绘制的目标位置也有多个(屏幕、打印机等),这种情况下,我们就可以使用桥接模式来将抽象部分和实现部分抽离开

具体实现

实现化角色(Implementor)

public interface DrawAPI {
    // 绘制形状方法,参数为形状类型
    void drawShape(String shapeType);
}

具体实现化角色(Concrete Implementor)

/ 创建 DrawAPI 接口的具体实现类,用于在屏幕上绘制图形
public class ScreenDrawAPI implements DrawAPI {
    // 实现绘制形状方法
    @Override
    public void drawShape(String shapeType) {
        System.out.println("在屏幕上绘制 " + shapeType);
    }
}


// 创建 DrawAPI 接口的具体实现类,用于在打印机上绘制图形
public class PrinterDrawAPI implements DrawAPI {
    // 实现绘制形状方法
    @Override
    public void drawShape(String shapeType) {
        System.out.println("在打印机上绘制 " + shapeType);
    }
}

抽象化角色(Abstraction)

// 定义一个抽象的形状类
public abstract class Shape {
    // 保护类型的 DrawAPI 变量,用于调用具体的绘制方法
    protected DrawAPI drawAPI;

    // 构造函数,接收一个 DrawAPI 类型的参数
    public Shape(DrawAPI drawAPI) {
        this.drawAPI = drawAPI;
    }

    // 抽象的绘制方法,由子类实现
    public abstract void draw();
}

扩展抽象化角色(Refined Abstraction)

// 创建一个圆形类,继承 Shape 抽象类
public class Circle extends Shape {
    // 构造函数,接收一个 DrawAPI 类型的参数
    public Circle(DrawAPI drawAPI) {
        super(drawAPI);
    }

    // 实现绘制方法
    @Override
    public void draw() {
        drawAPI.drawShape("圆形");
    }
}

// 创建一个矩形类,继承 Shape 抽象类
public class Rectangle extends Shape {
    // 构造函数,接收一个 DrawAPI 类型的参数
    public Rectangle(DrawAPI drawAPI) {
        super(drawAPI);
    }

    // 实现绘制方法
    @Override
    public void draw() {
        drawAPI.drawShape("矩形");
    }
}

客户角色(Client)

public class Client {
    public static void main(String[] args) {
        // 创建一个屏幕绘制实例
        DrawAPI screenDrawAPI = new ScreenDrawAPI();
        // 创建一个打印机绘制实例
        DrawAPI printerDrawAPI = new PrinterDrawAPI();

        // 使用屏幕绘制实例创建一个圆形
        Shape circle = new Circle(screenDrawAPI);
        // 在屏幕上绘制圆形
        circle.draw();

        // 使用打印机绘制实例创建一个圆形
        Shape circle2 = new Circle(printerDrawAPI);
        // 在打印机上绘制圆形
        circle2.draw();
    }
}

运行结果

在屏幕上绘制圆形
在打印机上绘制圆形

四、应用场景

以下部分内容摘自菜鸟教程

意图: 将抽象部分与实现部分分离,使它们都可以独立的变化。

主要解决: 在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。

何时使用: 实现系统可能有多个角度分类,每一种角度都可能变化。

如何解决: 把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。

关键代码: 抽象类依赖实现类。

应用实例: 1、猪八戒从天蓬元帅转世投胎到猪,转世投胎的机制将尘世划分为两个等级,即:灵魂和肉体,前者相当于抽象化,后者相当于实现化。生灵通过功能的委派,调用肉体对象的功能,使得生灵可以动态地选择。 2、墙上的开关,可以看到的开关是抽象的,不用管里面具体怎么实现的。

使用场景: 1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

注意事项: 对于两个独立变化的维度,使用桥接模式再适合不过了。


五、优缺点

优点

  1. 抽象和实现的分离。
  2. 优秀的扩展能力。
  3. 实现细节对客户透明。

缺点

桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。

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

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

相关文章

前端为什么使用svg图片

参考链接: 1.http://www.youngzi.cn/5392.html 2.https://baijiahao.baidu.com/s?id1728784571128338709&wfrspider&forpc SVG是什么?SVG有什么用?为什么要使用SVG?本篇文章就给大家介绍一下SVG的相关知识,让…

【Unity】HyBridCLR初探

完成目标: 创建热更新程序集加载热更新程序集,并执行其中热更新代码,打印 Hello, HybridCLR修改热更新代码,打印 Hello, World准备环境​ 安装Unity HybridCLR也支持2019.4.x,但新手请先按照下面要求跑通流程后,再根据安装HybridCLR文档尝试2019.4.x。 安装 2020.3.26+…

如何部署LVS负载均衡集群(DR模式)

目录 一、集群概念与NAT模式LVS集群 二、部署LVS集群(DR模式) 第一步 关闭防火墙和安全机制 第二步 手动配置ip_vs 第三步 安装ipvsadm工具 第四步 创建虚拟网卡 第五步 修改虚拟网卡配置内容 第六步 开启虚拟网卡并加入路由 第七步 调整proc相…

linux学习(韩顺平 一周学会linux)

b站链接:b站 共27个小时 P3-P85 linux基础篇 P86-P90 java定制篇 P91-P107 大数据shell篇 P108-P115 python定制篇 P117-P141 linux高级篇 P142-P153 面试题 四个阶段: 一、基本操作 二、配置 三、搭建开发环境 四、写一些基本的shell脚本 五、安全设置…

list容器语法

文章目录 listlist基本概念list的优点:list的缺点:重要性质 list 的使用方法list构造函数list 赋值和交换list 长度/大小操作list 插入元素和删除元素访问list 反转和排序sort链表排序案例forward_list(C11)forward_list 的使用方…

Openlayers实战:绘制点、线、圆、多边形

Openlayers地图中,绘制图形是非常重要的一个功能。Openlayers主要使用draw类来绘制图形,在实际项目中经常会绘制点、线、多边形、矩形等。 下面的示例是绘制点、线、圆形、多边形。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhuanlan),还是大剑师兰特(CSDN) * @此…

抖音关键词排名怎么做

抖音seo关键词搜索排名推广 产品及合作流程 了解抖音seo关键词搜索流量——用工具选择需要优化的关键词确认——预存套餐及服务——付款签约——开通关键词管理后台——建运营群流程化推进 如何选择优化的关键词? 先选3-5个主词 在工具分别输入主词 列出来的词&#xff0c…

【AJAX】跨域问题笔记

跨域 一、同源策略(Same-Origin Policy) 是浏览器的安全机制。 同源:协议、域名、端口号必须完全相同 客户端 服务端 违背同源策略就是跨域 二、如何解决跨域 1、JSOPN (1)JSONP是什么 JSONP(JSON with Padding…

Unity XR Interaction Toolkit(二)手柄交互

目录 一、结构配置 二、交互事件 1、事件设置 2、绑定设置 3、组合按键输入 4、事件挂载 三、代码响应 1、事件回调 2、数值获取 注意,本文的Toolkit版本在2.2以上,低版本没有样例和部分api,更新方法在第一张环境配置内 打开Packag…

力扣 46. 全排列

题目来源:https://leetcode.cn/problems/permutations/description/ C题解: 全排列每一次都需要从第一个元素开始遍历,所以不用ind标记开始元素,都从0开始,但需要一个数组used不断更新哪些元素已经被使用,遍…

基于SpringBoot+vue的家具销售电商平台设计与实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

k8s从节点加入主节点[preflight] Running pre-flight checks卡住(已解决)k8s常用问题解决

文章目录 一、写在前面二、问题排查1、执行join时加上-v2参数查看日志2、处理证书问题3、重启4、其他方法15、其他方法2 三、总结参考资料 一、写在前面 部署k8s时,主节点部署成功了,从节点1执行kubeadm join也成功了,从节点2执行kubeadm jo…

go专业数据结构与算法

go语言之专业数据结构与算法 2.数组概念 3.golang实现数组结构 4.golang实现数组迭代器 5.数组栈的高级实现 6.栈模拟低级递归 7.斐波那契数列栈模拟递归 8.递归实现文件夹遍历 9.栈模拟文件递归 10.层级展示文件夹 11.数组队列的实现 12.队列实现遍历文件夹 13.循环队列 14.链…

Java - 异常处理

异常介绍 对异常进行捕获,保证程序可以继续运行,提升程序的健壮性。 执行过程中所发生的异常时间可分为两大类: Error: Java虚拟机无法解决的严重问题。如:JVM系统内部错误,资源耗尽等严重情况。比如&…

Mars3d模型塌陷地底不显示的解决方法

问题场景: 1.发现模型或者矢量数据在拖拽地图视角的时候会发生漂移,加载的矢量数据或模型,浏览时会在地面漂移 2.开启深度检测之后,发现模型或者矢量数据会有部分被地形遮挡,无法看到 问题原因: 1.模型或…

【设计模式】第十八章:备忘录模式详解及应用案例

系列文章 【设计模式】七大设计原则 【设计模式】第一章:单例模式 【设计模式】第二章:工厂模式 【设计模式】第三章:建造者模式 【设计模式】第四章:原型模式 【设计模式】第五章:适配器模式 【设计模式】第六章&…

解决Ruoyi单体版本集成Echarts多图表时在Tab模式下不展示问题

目录 背景 一、Tab拆分后无法展示 1、环境简介 2、原始报表功能说明 3、tab切分遇到的问题 二、问题分析及解决 1、问题分析 2、问题解决 3、初始化时图表渲染 4、Tab切换时重渲 总结 背景 最近在使用ruoyi的单体化版本进行Echarts多图表展示时遇到一个问题,r…

C++primer(第五版)第十一章(关联容器)

关联容器支持高效的关键字查找和访问.两个主要的关联容器是map和set(其他的都是这两个的变种). map和multimap定义在头文件map中.set和multise定义在头文件set中.无序容器定义在头文件unordered_map和unordered_set中. 11.1使用关联容器 map的元素类型为pair,包含两个部分,key…

vue循环如何动态加载本地图片

显示效果&#xff1a; 代码&#xff1a; html&#xff1a; <el-tooltip :content"setTip(item)" placement"bottom"><img :src"setSrc(item)" alt"" width"20" height"20" /> </el-tooltip> …