设计模式之桥接模式

写在前面

本文看下桥接设计模式。

1:介绍

1.1:什么时候桥接设计模式

当一个业务场景由多个变化维度组成,并且这多个变化的维度到底有多少种情况是不确定,比如现在我们要为瑞幸咖啡写一个系统,很自然的,需要在系统中来表示咖啡,此时思考下,咖啡有哪些维度呢,当然首先是咖啡,这是确定的,但是以下的维度却是不确定的:

1:杯子的大小,可能是大杯,中杯,小杯
2:咖啡的味道,可能是原味,加糖,加奶,加糖和奶

对于以上的这个场景,我们就可以考虑使用桥接设计模式来实现。

1.2:UML类图

原型设计模式,包含如下元素:

1:抽象化(Abstraction)角色使用多个变化维度中一个来定义,一个定义一个抽象类
2:修正抽象化(RefinedAbstraction)角色继承抽象化角色,增加额外的操作,如无特殊需求,可不需要(我理解的)
3:实现化(Implementor)角色多个变化维度的一个
4:具体实现化角色实现化角色子类,提供某个变化维度的具体变化类型

UML图如下:

在这里插入图片描述

2:实例

源码 。

2.1:场景

现在有一个接口有一个方法需要一个List<String>的参数,但是客户端只能提供逗号分割的字符串作为参数,这样就可以定义一个接受逗号分割的字符串参数的接口,并提供实现进行适配。

2.2:程序

比如现在我们要为瑞幸咖啡写一个系统,很自然的,需要在系统中来表示咖啡,此时思考下,咖啡有哪些维度呢,当然首先是咖啡,这是确定的,但是以下的维度却是不确定的:

1:杯子的大小,可能是大杯,中杯,小杯
2:咖啡的味道,可能是原味,加糖,加奶,加糖和奶

这里我们将杯子的大小来作为抽象化角色。

  • 定义实现化角色
    定义了往咖啡中加什么调料。
// 咖啡中加糖,牛奶,等的抽象接口(实现化的顶层接口)
// 抽象的是在咖啡中加什么东西(糖,牛奶,等)
public interface ICoffeeAdditives {void addSomething();
}
  • 定义具体实现化角色
    这里分别实现加奶和加糖,其它的需要的类比添加接口。
// 加奶(最终会加到咖啡中,生成加奶咖啡)
public class Milk implements ICoffeeAdditives {@Overridepublic void addSomething() {System.out.println("加奶");}
}//加糖
public class Sugar implements ICoffeeAdditives {@Overridepublic void addSomething() {System.out.println("加糖");}
}
  • 定义抽象化角色
// 抽象化Abstraction
// 抽象是咖啡杯(大杯,小杯,中杯等)
public abstract class Coffee {// 保存一个实现话的引用,从而确定另外一个变化维度的信息protected ICoffeeAdditives additives;// 这里就好像桥一样,将抽象化和实现化连接在了一起,也正是桥接设计模式名称的来源public Coffee(ICoffeeAdditives additives){this.additives=additives;}// 客户点咖啡方法的抽象public abstract void orderCoffee(int count);
}

以上在构造函数中获取往咖啡加调料的类,就好像是一个桥一样,将杯子大小和咖啡加的调料建立了联系,这也是桥接设计模式中的桥接名称的来源。

  • 定义修正抽象话角色

这里仅仅是为了学习的完整性,但并无实际作用。

// 修正抽象化角色,增加新的操作,个人认为该类可有可无,如果没有特殊的需求
// ,在桥接设计模式中也可以没有该类
public abstract class RefinedCoffee extends Coffee {public RefinedCoffee(ICoffeeAdditives additives) {super(additives);}//    public void checkQuality() {
//        Random ran = new Random();
//        System.out.println(String.format("%s 添加%s", additives.getClass().getSimpleName(), ran.nextBoolean() ? "太多" : "正常"));
//    }
}
  • 定义被子大小维度的大杯和小杯
public class SmallCoffee extends RefinedCoffee {public SmallCoffee(ICoffeeAdditives coffeeAdditives) {super(coffeeAdditives);}@Overridepublic void orderCoffee(int count) {// 点了几杯咖啡System.out.println("点了" + count + " 小杯咖啡!");// 加什么super.additives.addSomething();}
}public class LargeCoffee extends RefinedCoffee {public LargeCoffee(ICoffeeAdditives coffeeAdditives) {super(coffeeAdditives);}@Overridepublic void orderCoffee(int count) {// 点了几杯咖啡System.out.println("点了" + count + " 大杯咖啡!");// 加什么super.additives.addSomething();}
}
  • 测试
// 两大杯加奶
@Test
public void testCase1() {RefinedCoffee largeWithMilk = new LargeCoffee(new Milk());largeWithMilk.orderCoffee(2);
}

输出:

点了2 大杯咖啡!
加奶
// 8小杯加糖
@Test
public void testCase2() {SmallCoffee smallCoffee = new SmallCoffee(new Sugar());smallCoffee.orderCoffee(8);
}

输出:

点了8 小杯咖啡!
加糖

写在后面

参考文章列表

秒懂设计模式之桥接模式(Bridge Pattern) 。

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

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

相关文章

2023.7.16 第五十九次周报

目录 前言 文献阅读:跨多个时空尺度进行预测的时空 LSTM 模型 背景 本文思路 本文解决的问题 方法论 SPATIAL 自动机器学习模型 数据处理 模型性能 代码 用Python编写的LSTM多变量预测模型 总结 前言 This week, I studied an article that uses LSTM to solve p…

【前端知识】React 基础巩固(二十三)——React 性能优化 SCU相关

React 基础巩固(二十三)——React 性能优化 SCU React 更新机制 React 的渲染流程 JSX -> 虚拟 DOM -> 真实 DOM React 的更新流程 props/state 改变 -> render函数重新执行 -> 产生新的DOM树 -> 新旧DOM树进行diff -> 计算出差异进行更新 -> 更新到真实…

Element分页组件自定义样式

样式效果 页面代码 <el-paginationsize-change"handleSizeChange"current-change"handleCurrentChange":current-page"page.page":page-sizes"[10, 20, 30, 40]":page-size"page.size"layout"total, sizes, prev, …

如何用https协议支持小程序

步骤一&#xff1a;下载SSL证书 登录数字证书管理服务控制台。在左侧导航栏&#xff0c;单击SSL 证书。在SSL证书页面&#xff0c;定位到目标证书&#xff0c;在操作列&#xff0c;单击下载。 在服务器类型为Nginx的操作列&#xff0c;单击下载。 解压缩已下载的SSL证书压缩…

Python中Threading对于TCP的使用

什么是多线程&#xff1f; 多线程类似于同时执行多个不同程序&#xff0c;多线程运行有如下优点&#xff1a; 使用线程可以把占据长时间的程序中的任务放到后台去处理。 用户界面可以更加吸引人&#xff0c;这样比如用户点击了一个按钮去触发某些事件的处理&#xff0c;可以弹…

springboot经典面试题2

问题&#xff1a;什么是Spring Boot的起步依赖&#xff08;Starter Dependencies&#xff09;&#xff1f;如何使用起步依赖&#xff1f; 答案&#xff1a;Spring Boot的起步依赖是一组预定义的依赖项&#xff0c;可以简化项目的配置和构建过程。可以通过在项目的构建配置文件…

[个人笔记] WinSrv批量添加DNS记录和条件转发器记录

Windows Server - 运维篇 第三章 WinSrv批量添加DNS记录和条件转发器记录 Windows Server - 运维篇系列文章回顾WinSrv批量添加DNS记录和条件转发器记录单条记录添加DNS条件转发器记录批量新增DNS条件转发器记录批量导出DNS条件转发器 参考来源 系列文章回顾 第一章 域控使用C…

使用 jmeter 进行审批类接口并发测试

目录 前言&#xff1a; 背景&#xff1a; 难点&#xff1a; 场景 a&#xff1a; 场景 b&#xff1a; 前言&#xff1a; 使用JMeter进行审批类接口的并发测试是一种有效的方法&#xff0c;可以模拟多个用户同时对接口进行审批操作&#xff0c;以评估系统在高负载情况下的性…

Java+Vue+Uniapp全端WMS仓库管理系统

详情图片为运行截图,功能列表: 1、数据管理:物料数据管理、物料Bom管理、物料组管理、物料分类管理、供应商管理、仓库管理、货位管理、车间管理 2、采购管理:物料标签管理、入库单管理、入库退货管理 3、质检管理:质检单管理(包括单据号、单据类型、创建时间、检验状态…

4. CSS用户界面样式

4.1什么是界面样式 所谓的界面样式,就是更改一些用户操作样式,以便提高更好的用户体验。 ●更改用户的鼠标样式 ●表单轮廓 ●防止表单域拖拽 4.2鼠标样式cursor li {cursor: pointer; }设置或检索在对象上移动的鼠标指针采用何种系统预定义的光标形状。 4.3轮廓线outline…

Mac如何将homebrew添加到系统路径

1.在终端下进入路径配置文件 sudo vim .zprofile 2.输入用户密码进入文本&#xff0c;键盘按i进入编辑模式&#xff08;左下角会显示INSERT状态&#xff09;&#xff0c;配置环境变量&#xff1a; export PATH/opt/homebrew/bin:$PATH3.Esc退出编辑模式&#xff0c;输入**&am…

排序算法第三辑——交换排序

目录 ​编辑 一&#xff0c;交换排序算法的简介 二&#xff0c;冒泡排序 冒泡排序代码&#xff1a;排升序 三&#xff0c;快速排序 1.霍尔大佬写的快速排序 2.挖坑法 3.前后指针法 四&#xff0c;以上代码的缺陷与改正方法 三数取中 三路划分&#xff1a; 五&#…

【电子学会】2023年05月图形化四级 -- 计算圆的面积和周长

计算圆的面积和周长 编写程序计算圆的面积和周长。输入圆的半径&#xff0c;程序计算出圆的面积和周长&#xff0c;圆的面积等于3.14*半径*半径&#xff1b;圆的周长等于2*3.14*半径。 1. 准备工作 &#xff08;1&#xff09;保留舞台中的小猫角色和白色背景&#xff1b; 2…

Stream流式思想

什么是Stream&#xff1f; 也叫Stream流&#xff0c;是Jdk8开始新增的一套API (java.util.stream.*)&#xff0c;可以用于操作集合或者数组的数据。 优势&#xff1a; Stream流大量的结合了Lambda的语法风格来编程&#xff0c;提供了一种更加强大&#xff0c;更加简单的方式操…

从 Blender 导出动画视频

Blender Tutorial - How To Export Video Files 要导出编辑完的视频&#xff0c;你需要先设置好输出的格式、分辨率、帧率、位置等参数&#xff0c;然后选择渲染动画的选项&#xff0c;等待渲染完成后&#xff0c;你就可以在指定的位置找到生成的视频文件。 具体步骤如下&…

Python 列表 sort()函数使用详解

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 sort函数使用详解 1、升序降序2、sort()和sorted()的区别3、切片排序4、指定排序…

vue封装短信验证码,刷新缓存倒计时

HTML代码 <a-form-item field"verifyCode" label"验证码:"><a-input v-model"formData.verifyCode" placeholder"短信验证码" class"login-form-button" allow-clear><template #append><span:class&q…

TypeScript笔记

文章目录 什么是TS前期准备安装TSTS配置文件 基础类型原始类型 object类型 数组类型 元组类型 枚举 函数类型可选参数和默认参数剩余参数 any任意类型 高级类型交叉类型联合类型 接口类泛型类型别名参考 什么是TS 官网介绍&#xff1a;TypeScript是JavaScript类型的超集&#…

力扣160. 相交链表

题目 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。题目数据保证整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&#xff0c;链表必须保持其原始结构。 链接&am…

深度学习项目四:创建自定义数据集的dataset, DataLoader

深度学习项目四:创建自定义数据集的dataset, DataLoader 文章目录 深度学习项目四:创建自定义数据集的dataset, DataLoader前言一、构建dataset基本类二、创建train_dataset,test_dataset及相应DataLoader1.数据集的index创建2.创建自定义dataset类3.划分训练集和测试集,创建…