设计模式之桥接模式

写在前面

本文看下桥接设计模式。

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…

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证书压缩…

使用 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…

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

目录 ​编辑 一&#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…

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

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

TypeScript笔记

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

飞书ChatGPT机器人 – 打造智能问答助手实现无障碍交流

文章目录 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 前言 在飞书中创建chatGPT机器人并且对话&#xff0c;在下面操作步骤中…

Flask结合gunicorn和nginx反向代理的生产环境部署及踩坑记录

个人博客&#xff1a;https://xzajyjs.cn 前言 之前自己写的flask使用gunicorn上线生产环境没有什么问题&#xff0c;但是最近搭建了一个现成的flask项目&#xff0c;当使用python直接运行时不会有问题&#xff0c;而使用gunicorn时则会出现一些问题。 部署过程 运行测试 这…

听GPT 讲K8s源代码--pkg(一)

在 Kubernetes 代码仓库中&#xff0c;pkg/api和pkg/apis目录都包含用于定义 Kubernetes API 对象的代码&#xff0c;但它们的作用略有不同。 pkg/api目录包含 Kubernetes 的旧版本 API 对象定义&#xff0c;这些定义在 Kubernetes 1.7 版本之前使用。这些对象定义已经过时&…

k8s 持久化存储

我们继续来查看 k8s 的卷&#xff0c;上一次我们分享了将磁盘挂载到容器中&#xff0c;empyDir 和 gitRepo 都是会随着 pod 的启动而创建&#xff0c;随着 pod 的删除而销毁 那么我们或许会有这样的需求&#xff0c;期望在 pod 上面读取节点的文件或者使用节点的文件系统来访问…

Spring Boot 中的 Redis 的数据操作配置和使用

Spring Boot 中的 Redis 的数据操作配置和使用 Redis 是一种高性能的 NoSQL 数据库&#xff0c;它支持多种数据结构&#xff0c;包括字符串、哈希、列表、集合和有序集合。Redis 还提供了丰富的命令&#xff0c;可以对数据进行快速的 CRUD 操作。Spring Boot 是一个基于 Sprin…

基于单片机智能加湿器 水位防干烧加湿器的设计与实现

功能介绍 以51/STM32单片机作为主控系统&#xff1b;LCD1602液晶显示当前温湿度&#xff0c;当前模式&#xff0c;湿度下限;按键设置湿度下限&#xff0c;当湿度低于下限时开启加湿器;水位传感器检查加湿器是否有水&#xff0c;如果没有水到话加湿器不进行工作&#xff0c;蜂鸣…

怎么用PDF24 Tools工具在线进行PDF文件合并

PDF文件是经常会被用到&#xff0c;它在我们的日常生活和工作中扮演着重要的角色。PDF文件合并是将多个PDF文件合并为单个文件&#xff0c;这个过程通常是为了方便管理多个PDF文件&#xff0c;或者将多个PDF文件合并为一个整体以便于共享或打印。既然如此&#xff0c;如何快速合…

kotlin forEach循环return/break

kotlin forEach循环return/break fun main(args: Array<String>) {var a mutableListOf("0", "1", "2", "3", "4")var b mutableListOf<String>()a.forEachIndexed { index, s ->if (index > 2) {retu…

【Mac使用笔记】之 Homebrew

Homebrew更新&#xff1a; brew update && brew upgrade 当出现错误&#xff1a; fatal: couldnt find remote ref refs/heads/master 执行&#xff1a; brew tap --repair Ruby安装&#xff1a; 1、查看当前Homebrew版本&#xff1a; brew --version2、查看当前…

libbpf-bootstrap 开发指南:概念与如何安装

目录 概念 如何安装& 使用 git 地址 使用git clone 下载代码 安装依赖环境 安装libbpf 编译example 概念 libbpf-bootstrap 是一个项目&#xff0c;旨在帮助开发者快速启动和开发使用 eBPF (Extended Berkeley Packet Filter) 和 libbpf 的程序。eBPF 是一种可以在…