设计模式:中介者模式 Mediator

目录

  • 前言
  • 问题
  • 解决方案
  • 结构
  • 代码


前言

中介者是一种行为设计模式,能让你减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。


问题

假如你有一个创建和修改客户资料的对话框, 它由各种控件组成, 例如 文本框(TextField)、复选框(Checkbox) 和 按钮(Button)等。
在这里插入图片描述
某些表单元素可能会直接进行互动。 例如, 选中“我有一只狗”复选框后可能会显示一个隐藏文本框用于输入狗狗的名字。 另一个例子是提交按钮必须在保存数据前校验所有输入内容。
在这里插入图片描述
如果直接在表单元素代码中实现业务逻辑, 你将很难在程序其他表单中复用这些元素类。 例如, 由于复选框类与狗狗的文本框相耦合, 所以将无法在其他表单中使用它。 你要么使用渲染资料表单时用到的所有类,要么一个都不用。

解决方案

中介者模式建议你停止组件之间的直接交流并使其相互独立。这些组件必须调用特殊的中介者对象, 通过中介者对象重定向调用行为,以间接的方式进行合作。最终,组件仅依赖于一个中介者类,无需与多个其他组件相耦合。

在资料编辑表单的例子中, 对话框(Dialog) 类本身将作为中介者, 其很可能已知自己所有的子元素, 因此你甚至无需在该类中引入新的依赖关系。
在这里插入图片描述
绝大部分重要的修改都在实际表单元素中进行。 让我们想想提交按钮。之前,当用户点击按钮后,它必须对所有表单元素数值进行校验。 而现在它的唯一工作是将点击事件通知给对话框。 收到通知后, 对话框可以自行校验数值或将任务委派给各元素。 这样一来, 按钮不再与多个表单元素相关联,而仅依赖于对话框类。

你还可以为所有类型的对话框抽取通用接口, 进一步削弱其依赖性。 接口中将声明一个所有表单元素都能使用的通知方法, 可用于将元素中发生的事件通知给对话框。 这样一来,所有实现了该接口的对话框都能使用这个提交按钮了。

采用这种方式, 中介者模式让你能在单个中介者对象中封装多个对象间的复杂关系网。 类所拥有的依赖关系越少, 就越易于修改、扩展或复用。

结构

在这里插入图片描述

代码

#include <iostream>
#include <string>
#include <memory>
#include <map>
using namespace std;class AbstractComponent{
public:virtual void operation()=0;virtual ~AbstractComponent(){}
};class AbstractMediator{
public:virtual void notify(const string& sender)=0;virtual void addComponent(const string& name,shared_ptr<AbstractComponent> component)=0;virtual ~AbstractMediator(){}
};
class Dialog:public AbstractMediator{
public:void notify(const string& sender) override {if (sender == "button") {// 当按钮被触发时,协调复选框也执行操作cout << "中介者:按钮被按下,触发复选框操作" << endl;if (m_component.find("checkbox") != m_component.end()) {m_component["checkbox"]->operation();}} else if (sender == "checkbox") {cout<<"end"<<endl;}}void addComponent(const string& name,shared_ptr<AbstractComponent> component){m_component.insert(make_pair(name,component));}
private:map<string,shared_ptr<AbstractComponent>> m_component;
};class Button:public AbstractComponent{
public:Button(shared_ptr<AbstractMediator> mediator){m=mediator;}void operation() override {cout << "按钮被按下" << endl;// 自身状态变化后,通过中介者通知其他组件m->notify("button"); }
private:shared_ptr<AbstractMediator> m;
};
class Checkbox:public AbstractComponent{
public:Checkbox(shared_ptr<AbstractMediator> mediator){m=mediator;}void operation() override{cout << "调用复选框" << endl;// 自身状态变化后,通过中介者通知其他组件m->notify("checkbox"); }
private:shared_ptr<AbstractMediator> m;
};int main(){auto dialog=make_shared<Dialog>();auto button=make_shared<Button>(dialog);auto checkbox=make_shared<Checkbox>(dialog);dialog->addComponent("button",button);dialog->addComponent("checkbox",checkbox);button->operation();cout<<"----------------"<<endl;checkbox->operation();return 0;
}

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

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

相关文章

计算机基础速通--数据结构·线性表应用

如有问题大概率是我的理解比较片面&#xff0c;欢迎评论区或者私信指正。 考察线性表&#xff0c;核心围绕其存储结构特性、核心操作实现、场景应用选型三大维度&#xff0c;重点检验对基础概念的理解、代码实现能力及问题分析能力&#xff0c;通常会结合算法设计、复杂度分析和…

LeetCode Hot 100:42. 接雨水

题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 解析 和题目 盛水最多的容器 类似&#xff0c; LeetCode Hot 100&#xff1a;11. 盛最多水的容器-CSDN博客 只是这里将每一个柱子视为一个宽度为…

【C语言入门级教学】字符指针变量

文章目录1.字符指针变量2. 数组指针变量2.1 数组指针变量初始化3.⼆维数组传参的本质1.字符指针变量 在指针的类型中我们知道有⼀种指针类型为字符指针 char* ; ⼀般使⽤: int main() { char ch w; char* pc &ch;//pc的类型是char**pcw;//对pc解引用 修改ch存放的内容…

【Shell脚本自动化编写——报警邮件,检查磁盘,web服务检测】

Shell脚本自动化编写Shell脚本自动化编写一、判断当前磁盘剩余空间是否有20G&#xff0c;如果小于20G&#xff0c;则将报警邮件发送给管理员&#xff0c;每天检查一次磁盘剩余空间。第一步&#xff1a;准备工作第二步&#xff1a;配置邮件信息第三步&#xff1a;检查磁盘的自动…

Java 接口(下)

三、接口的继承性【基础重点】 1. Java中的接口之间的继承关系是多继承&#xff0c;一个接口可以有多个父接口(1) 语法&#xff1a;interface 接口名 extends 父接口1,父接口2{} 2. 类和接口之间是多实现的关系&#xff1a;一个类可以同时实现多个接口(1) 语法&#xff1a;clas…

学习游戏制作记录(各种水晶能力以及多晶体)8.1

1.实现创建水晶并且能与水晶进行交换位置的能力创建好水晶的预制体&#xff0c;添加动画控制器&#xff0c;传入待机和爆炸的动画创建Crystal_Skill_Control脚本&#xff1a;挂载在水晶预制体上private float crystalExstTime;//水晶存在时间public void SetupCrystal(float _c…

在vscode 如何运行a.nut 程序(Squirrel语言)

在 VS Code 中运行 Squirrel 语言编写的 .nut 程序&#xff0c;需要先配置 Squirrel 运行环境并安装相关插件&#xff0c;具体步骤如下&#xff1a; 一、安装 Squirrel 解释器 Squirrel 程序需要通过其官方解释器 squirrel 或 sq 执行&#xff0c;首先需要安装解释器&#xf…

【数据结构】生活中的数据结构:从吃饭与编程看栈与队列思维

生活中的数据结构&#xff1a;从吃饭与编程看栈与队列思维 在软件开发的世界里&#xff0c;栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;是两种基础的数据结构&#xff0c;它们以不同的顺序管理数据&#xff1a;栈遵循后进先出&#xff08;LIFO&#x…

牛客——接头密匙

题目链接&#xff1a;牛客--接头密匙 该题是一个很显然的前缀树问题&#xff0c;只需要构建a中所有数组对应的前缀树&#xff0c;之后求b所处前缀个数即可。关于前缀树的构建&#xff0c;可以观看左老师算法讲解045的视频&#xff0c;简单来讲就是用特殊字符将实际数据隔开&…

【Linux基础知识系列】第六十三篇 - 文件编辑器基础:vim

在 Linux 系统中&#xff0c;文本编辑器是系统管理员和开发人员不可或缺的工具。vim 是一个功能强大的文本编辑器&#xff0c;广泛应用于 Linux 系统中。它支持多种编辑模式&#xff0c;提供了丰富的文本编辑功能&#xff0c;适用于编写代码、配置文件和文档。掌握 vim 的基本使…

音频驱动的视觉特效:粒子、动画与Shader的融合技术

音频驱动视觉效果的实现与应用1. 引言在互动媒体、游戏和数字艺术领域&#xff0c;音频数据实时控制视觉元素已成为核心技术&#xff0c;它能创造沉浸式体验&#xff0c;增强用户参与感。例如&#xff0c;音乐会可视化或VR游戏中&#xff0c;音频信号驱动粒子流动、动画变化和S…

机器学习环境配置

【终极指南】吃透机器学习环境配置&#xff1a;从Conda、CUDA到Docker容器化 大家好&#xff01;在机器学习的旅程中&#xff0c;一个稳定、可复现的环境是成功的基石。 第一部分&#xff1a;核心理念——为何环境配置如此重要&#xff1f; 任何机器学习模型的运行&#xff0c;…

【14】大恒相机SDK C#开发 ——Bitmap.UnlockBits()什么意思?有什么用?bmpData.Scan0;什么意思?有什么用?

文章目录1 Bitmap.UnlockBits()2 bmpData.Scan01 Bitmap.UnlockBits() 在 C# 中&#xff0c;Bitmap.UnlockBits() 方法的作用是解锁通过 Bitmap.LockBits() 方法锁定的位图数据&#xff0c;并释放相关的位图数据结构。 当你使用 Bitmap.LockBits() 方法锁定位图数据时&#x…

什么是doris

文章目录简介使用场景Apache Doris 主要应用于以下场景&#xff1a;实时数据分析&#xff1a;湖仓融合分析&#xff1a;半结构化数据分析&#xff1a;Apache Doris 的核心特性详细请看官方文档&#xff1a; Apache Doris介绍简介 Apache Doris 是一款基于 MPP 架构的高性能、实…

python+pyside6的简易画板

十分简单的一个画板程序&#xff0c;用QLabel控件作为画布&#xff0c;在画布上可以画出直线、矩形、填充矩形、园&#xff0c;椭园、随手画、文本等内容。将原先发布的画板程序中的画文本方法修改成了原位创建一编辑框&#xff0c;编辑框失去焦点后&#xff0c;即将文本画在画…

【数据可视化-76】从释永信被查,探索少林寺客流量深度分析:Python + Pyecharts 炫酷大屏可视化(含完整数据和代码)

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

WPF TreeView自带自定义滚动条

放在TreeView.Resources中&#xff1a;<Style TargetType"ScrollBar"><Setter Property"Stylus.IsPressAndHoldEnabled" Value"false"/><Setter Property"Stylus.IsFlicksEnabled" Value"false"/><Set…

MongoDB 详细用法与 Java 集成完整指南

MongoDB 详细用法与 Java 集成完整指南 目录 MongoDB 基础概念MongoDB 安装与配置MongoDB Shell 基本操作Java 环境准备Java MongoDB 驱动集成连接配置基本 CRUD 操作高级查询操作索引操作聚合管道事务处理Spring Boot 集成最佳实践 1. MongoDB 基础概念 1.1 核心概念对比 …

【Flutter3.8x】flutter从入门到实战基础教程(四):自定义实现一个自增的StatefulWidget组件

fluttet中实现一个自定义的StatefulWidget组件&#xff0c;可以在数据变化后&#xff0c;把最新的页面效果展示给客户 实现效果实现代码 pages文件夹下新加一个counter_page.dart文件 class CounterPage extends StatefulWidget {const CounterPage({super.key});overrideState…

[AI8051U入门第十三步]W5500实现MQTT通信

前言 学习目标: 1、学习MQTT协议 2、了解MQTT数据帧格式 3、自己编写MQTT程序 4、调试MQTT程序一、MQTT协议介绍 MQTT(Message Queuing Telemetry Transport) 是一种轻量级的 发布/订阅(Pub/Sub) 消息传输协议,专为 低带宽、高延迟或不可靠网络 环境设计,广泛应用于 物…