当前位置: 首页 > news >正文

中介者模式(Mediator Pattern)、桥接模式(Bridge Pattern) 和 策略模式(Strategy Pattern)

中介者模式(Mediator Pattern)桥接模式(Bridge Pattern) 和 策略模式(Strategy Pattern) 都是常见的设计模式,它们解决不同类型的问题。我们将通过 Swift 示例来说明它们的使用场景,并附上简洁的图示。


1. 中介者模式(Mediator Pattern)

目的:中介者模式通过引入一个中介者对象,来减少类与类之间的直接耦合,避免多对多的依赖关系,使得系统中的类之间通过中介者进行交互。

使用场景

  • 当多个类之间的交互复杂且不易管理时,通过引入中介者模式可以减少各个类之间的依赖关系。
  • 适用于 UI 组件之间的交互,例如聊天系统中多个用户的消息传递,或多个模块之间的消息通知。

Swift 示例

假设我们有一个聊天系统,多个用户之间互相发送消息,使用中介者来协调消息的传递:

// 中介者协议
protocol ChatMediator {func sendMessage(_ message: String, from user: User)func addUser(_ user: User)
}// 用户类
class User {let name: Stringvar mediator: ChatMediator?init(name: String) {self.name = name}func sendMessage(_ message: String) {mediator?.sendMessage(message, from: self)}func receiveMessage(_ message: String) {print("\(name) received message: \(message)")}
}// 中介者实现
class ChatRoom: ChatMediator {private var users: [User] = []func addUser(_ user: User) {users.append(user)user.mediator = self}func sendMessage(_ message: String, from user: User) {for u in users where u !== user {u.receiveMessage(message)}}
}// 使用中介者模式
let chatRoom = ChatRoom()let user1 = User(name: "Alice")
let user2 = User(name: "Bob")
let user3 = User(name: "Charlie")chatRoom.addUser(user1)
chatRoom.addUser(user2)
chatRoom.addUser(user3)user1.sendMessage("Hello, everyone!")  // Alice 发送消息,Bob 和 Charlie 会收到消息

图示

      +------------+| ChatRoom   |+------------+|+---------+----------+|         |          |
+---+     +---+      +---+
| A |     | B |      | C |
+---+     +---+      +---+

2. 桥接模式(Bridge Pattern)

目的:桥接模式的核心思想是将抽象与实现分离,使得二者可以独立扩展。通过桥接模式,你可以将类的功能分解为多个维度的类,并将这些维度的类组合起来,减少子类的数量。

使用场景

  • 当你需要将一个类的抽象部分与其实现部分解耦,使得二者可以独立地变化时。
  • 适用于设备控制系统、图形绘制系统等场景。

Swift 示例

假设我们有一个图形绘制系统,需要同时支持不同的形状(如圆形、方形)和不同的绘制方式(如矢量绘制、位图绘制):

// 实现接口
protocol DrawingAPI {func drawCircle(radius: Double)
}// 不同的绘制方式(实现)
class VectorDrawing: DrawingAPI {func drawCircle(radius: Double) {print("Drawing a vector circle with radius \(radius)")}
}class RasterDrawing: DrawingAPI {func drawCircle(radius: Double) {print("Drawing a raster circle with radius \(radius)")}
}// 抽象部分
protocol Shape {var drawingAPI: DrawingAPI { get }func draw()
}// 圆形类
class Circle: Shape {var drawingAPI: DrawingAPIvar radius: Doubleinit(drawingAPI: DrawingAPI, radius: Double) {self.drawingAPI = drawingAPIself.radius = radius}func draw() {drawingAPI.drawCircle(radius: radius)}
}// 使用桥接模式
let vectorDrawing = VectorDrawing()
let rasterDrawing = RasterDrawing()let circle1 = Circle(drawingAPI: vectorDrawing, radius: 5)
circle1.draw()  // 输出: Drawing a vector circle with radius 5let circle2 = Circle(drawingAPI: rasterDrawing, radius: 10)
circle2.draw()  // 输出: Drawing a raster circle with radius 10

图示

  +------------------+|  Shape           |+------------------+^|+------------+| Circle     |+------------+|+-------------+| DrawingAPI  |+-------------+/         \/           \
+--------+   +--------+
| Vector |   | Raster |
+--------+   +--------+


3. 策略模式(Strategy Pattern)

目的:策略模式用于将一系列的算法封装起来,让它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。

使用场景

  • 当你有多种算法,且希望在运行时决定使用哪种算法时。
  • 适用于需要动态选择算法或者行为的场景,比如支付方式选择、排序策略等。

Swift 示例

假设我们有一个应用,允许用户选择不同的排序算法:

 

图示

// 排序策略协议
protocol SortStrategy {func sort(_ data: [Int]) -> [Int]
}// 具体的排序算法
class QuickSort: SortStrategy {func sort(_ data: [Int]) -> [Int] {return data.sorted()}
}class MergeSort: SortStrategy {func sort(_ data: [Int]) -> [Int] {return data.sorted()}
}class BubbleSort: SortStrategy {func sort(_ data: [Int]) -> [Int] {var array = datafor i in 0..<array.count {for j in 0..<array.count-i-1 {if array[j] > array[j+1] {array.swapAt(j, j+1)}}}return array}
}// Context 使用策略模式
class SortContext {private var strategy: SortStrategyinit(strategy: SortStrategy) {self.strategy = strategy}func setStrategy(_ strategy: SortStrategy) {self.strategy = strategy}func executeStrategy(data: [Int]) -> [Int] {return strategy.sort(data)}
}// 使用策略模式
let context = SortContext(strategy: QuickSort())let data = [5, 2, 9, 1, 5, 6]
let sortedData = context.executeStrategy(data: data)
print(sortedData)  // 输出: [1, 2, 5, 5, 6, 9]// 切换排序算法
context.setStrategy(BubbleSort())
let bubbleSortedData = context.executeStrategy(data: data)
print(bubbleSortedData)  // 输出: [1, 2, 5, 5, 6, 9]

lua

       +-----------------+| SortContext     |+-----------------+|+-------+--------+|                |
+-----------+     +-----------+
| QuickSort |     | BubbleSort |
+-----------+     +-----------+|                |+------------+   +------------+| MergeSort  |   | SortStrategy|+------------+   +------------+


总结对比表:

模式目的/特点使用场景Swift 示例
中介者模式降低类之间的耦合,通过中介者来协调交互多个对象之间存在复杂交互时,避免直接引用其他对象聊天系统中用户通过中介者交换消息
桥接模式将抽象和实现分离,允许它们独立变化抽象部分和实现部分变化频繁的场景图形绘制系统,不同的形状和绘制方式
策略模式将算法封装成独立的策略类,使得算法可以互换需要根据不同情境使用不同算法的场景排序算法的选择,可以动态切换不同的排序策略

这些设计模式帮助解决不同类型的耦合问题,允许我们编写更加灵活、可扩展、可维护的代码。根据实际需求选择合适的模式,可以提升代码的可维护性和复用性。

相关文章:

中介者模式(Mediator Pattern)、桥接模式(Bridge Pattern) 和 策略模式(Strategy Pattern)

中介者模式&#xff08;Mediator Pattern&#xff09;、桥接模式&#xff08;Bridge Pattern&#xff09; 和 策略模式&#xff08;Strategy Pattern&#xff09; 都是常见的设计模式&#xff0c;它们解决不同类型的问题。我们将通过 Swift 示例来说明它们的使用场景&#xff0…...

客户案例:基于慧集通打通聚水潭电商ERP与用友U8系统集成之路

一、引言 本原型客户是 生物科技公司&#xff0c;其公司系列抗菌抗病毒产品广泛应用于医疗用品、纺织服饰、家纺用品、母婴护理、女性用品、个人防护等多个领域。在知识产权方面&#xff0c;公司在专业领域已获得商标和专利近百项&#xff0c;创新能力得到了国家及行业内普遍认…...

阿里云clb是什么

传统型负载均衡服务 ‌阿里云CLB&#xff08;Classic Load Balancer&#xff09;是阿里云提供的一种传统型负载均衡服务&#xff0c;主要用于将访问流量根据转发策略分发到后端多台云服务器。‌‌ CLB的定义和功能 CLB是一种流量分发控制服务&#xff0c;通过设置虚拟服务地…...

【Cursor编辑器】自用经验和实操(迭代更新)

1.启动composer crtl I 2.生成直接一直问加载 3. 实操 生成个知识图谱&#xff0c;使用csv文件里面的数据创关系和节点。...

【学习笔记】ChatGPT原理与应用开发——基础科普

HuggingLLM&#xff08;ChatGPT原理与应用开发&#xff09; 原文链接&#xff1a;HuggingLLM&#xff08;ChatGPT原理与应用开发&#xff09;-课程详情 | Datawhale 此处仅为学习记录和总结 1&#xff1a;基础科普 1.1&#xff1a;自然语言背景 图灵测试 如果一个人&#x…...

基于Web的实验中心工作管理网站的设计与实现

写作任务 一、课题背景 实验中心承担了全校计算机公共基础课程和学院专业课程&#xff0c;需要对实验中心工作进行有效的管理。 二、课题任务 本课题设计和实现实验中心工作管理系统。 系统的主要内容包括&#xff1a; &#xff08;1&#xff09;人员管理&#xff1b; &am…...

docker 安装minio

docker pull minio/minio #启动 mkdir -p /root/minio/config mkdir -p /root/minio/datadocker run -d \--name minio \-p 9002:9000 \-p 9001:9001 \--restartalways \-v /root/minio/data:/data \-v /root/minio/config:/root/.minio \-e "MINIO_ACCESS_KEYminioadmin…...

ubuntu下ipmi的使用(4028)

参考ubuntu系统下配置IPMI_ubuntu ipmi-CSDN博客 参考&#xff1a;ipmitool ubuntu 安装_ipmi centos ubuntu使用总结-CSDN博客 1.安装 sudo apt-get -y install ipmitool 2.加载 modprobe ipmi_msghandlermodprobe ipmi_devintfmodprobe ipmi_si 3.使用,查看不到的话&am…...

周记-唐纳德的《计算机程序设计艺术》

用代码生成代码 开发一个协议&#xff0c;字段有些多&#xff0c;每个字段是QT的属性&#xff0c;需要写Q_PROPERTY&#xff0c;一个一个编辑的话比较繁琐&#xff0c;耗费时间。后来就用代码生成了头文件和源文件&#xff0c;get和set还有signal函数&#xff0c;内容基本都是…...

极品飞车6的快捷键与车辆等级

极品飞车&#xff0c;英文全称为Need for Speed&#xff0c;是EA公司于1994年开始研发的赛车类竞技游戏。从1996年的《极品飞车-特别版》、2002年的《极品飞车:闪电追踪2》、2005年的《极品飞车:地下狂飙2》、到2024年《极品飞车:集结》&#xff0c;是70后、80年、90年等几代人…...

计算机毕业设计Python+知识图谱大模型AI医疗问答系统 健康膳食推荐系统 食谱推荐系统 医疗大数据 机器学习 深度学习 人工智能 爬虫 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

纯真社区版IP库CZDB数据格式使用教程

1. 概述 纯真社区版IP库是一种免费且公开的IP地理位置数据库&#xff0c;主要面向非商业用途。其最新推出的CZDB格式是一种全新的数据文件格式&#xff0c;自2024年10月起将成为官方维护和更新的唯一版本。该格式支持同时存储IPv4和IPv6地址信息&#xff0c;具备以下优点&…...

Linux(Centos 7.6)软件包安装

Linux软件安装&#xff0c;常见的有三种方式&#xff0c;rpm方式、yum方式、源码编译安装方式。其中rpm方式可能存在依赖方式&#xff0c;可能会比较麻烦&#xff1b;源码编译安装同样可能会缺少一些编译需要的软件需要安装&#xff0c;也会比较麻烦&#xff1b;相对比较好的方…...

[WASAPI]音频API:从Qt MultipleMedia走到WASAPI,相似与不同

[WASAPI] 从Qt MultipleMedia 来看WASAPI 最近在学习有关Windows上的音频驱动相关的知识&#xff0c;在正式开始说WASAPI之前&#xff0c;我想先说一说Qt的Multiple Media&#xff0c;为什么呢&#xff1f;因为Qt的MultipleMedia实际上是WASAPI的一层封装&#xff0c;它在是线…...

【畅购商城】微信支付之支付模块

目录 支付页面 接口 后端实现 前端实现​​​​​​​ ​​​​​​​支付页面 步骤一&#xff1a;创建 flow3.vue组件 步骤二&#xff1a;引入第三方资源&#xff08;js、css&#xff09; <script> import TopNav from ../components/TopNav import Footer from …...

网络安全专有名词详解_2

57.Webshell 就是以ASP、php、jsp、cgi等网页文件形式存在的一种命令执行环境&#xff0c;也叫做网页的后门&#xff0c;可以上传下载文件&#xff0c;查看数据库和执行任意的程序命令等。 58.跨站攻击 XSS&#xff0c;是指攻击者利用网站程序对用户输入过滤不足&#xff0c;输…...

【传感器技术与应用】第2章 基本电量传感器,电位器式传感器,电感式传感器,电容式传感器

注作者了解更多 我的其他CSDN专栏 毕业设计 求职面试 大学英语 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数…...

【day20】集合深入探讨

模块19回顾 在深入探讨模块20之前&#xff0c;让我们回顾一下day19中的关键内容&#xff1a; Collection集合&#xff1a;单列集合的顶级接口&#xff0c;提供了add、addAll、clear、size、isEmpty、remove、toArray、contains等方法。迭代器&#xff08;Iterator&#xff09…...

【英语语法】用must表对过去推测时,要用完成时must have been / must have done(不能直接用过去时)

文章目录 疑问解释1. 表达过去的推测2. 与时态一致3. 语法结构的限制4. 例子对比总结 疑问 This must have been a year-round activity as no structures have been found which would have been used to shelter animals in the winter. 为什么must表示对过去推测要用完成时&…...

数值计算期末考试重点(一)(黄云清版教材)

1.误差的分类 2.绝对误差和绝对误差限 3.绝对误差和绝对误差限 例题&#xff08;课后习题1.2&#xff09; 4.有效数字 例题&#xff08;课后习题1.6&#xff09; 5.算法的数值稳定性 例题&#xff08;课后习题1.9&#xff09; 这个手算比较艰难&#xff0c;还是给计算机算吧&am…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码&#xff1a;冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...