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

相似模式区分

总览

模式核心意图典型场景
中介者协调多个对象间的复杂交互智能家居中控、聊天室、GUI组件联动
观察者一对多的通知机制事件监听、消息订阅、数据绑定
门面为子系统提供统一入口API封装、SDK入口、简化调用

中介者 vs 观察者

维度中介者模式观察者模式
核心意图集中协调多对象间的双向交互一对多的单向通知
结构差异中介者知道所有同事,同事只知道中介者主题知道所有观察者,观察者只知道主题
关注点对象间的交互规则和联动逻辑状态变化的通知分发
典型场景智能家居中控、聊天室、工作流引擎事件监听、消息订阅、数据绑定

逐步区分法

  1. 如果对象间需要双向交互(A变化影响B,B变化可能再影响A)→ 选中介者
  2. 如果只是单向通知(主题变化通知观察者,观察者不反向影响主题)→ 选观察者
  3. 如果联动规则复杂需要集中管理 → 选中介者

简单记忆口诀:中介者管双向协调,观察者管单向通知。

推荐:大多数场景下,复杂联动用中介者,简单通知用观察者。Spring事件机制是观察者的变体,但可以用于简单联动场景。

中介者 vs 门面

维度中介者模式门面模式
核心意图协调多对象间的交互,降低耦合为复杂子系统提供统一入口,简化调用
结构差异中介者参与业务逻辑,协调对象间的交互门面只是封装调用入口,不参与子系统内部逻辑
关注点对象间的交互规则子系统的使用接口
典型场景聊天室、GUI组件联动、工作流引擎API封装、SDK入口、简化配置

逐步区分法

  1. 如果需要协调多个对象间的交互(对象间有联动)→ 选中介者
  2. 如果只是简化调用入口(提供一个统一接口调用多个子系统)→ 选门面
  3. 如果对象需要反向通知中介者 → 选中介者(门面是单向的)

简单记忆口诀:中介者管交互,门面管入口。

推荐:门面用于简化外部调用,中介者用于协调内部交互。两者可以组合使用:门面作为外部入口,中介者协调内部逻辑。

练习题目

智能家居中控系统

题目描述:小明正在设计一个智能家居系统,系统中有灯(Light)、窗帘(Curtain)、空调(AC)三种设备,它们通过智能家居中控(中介者)来协调联动。设备之间不直接通信,所有联动逻辑由中控负责。

中控的联动规则:

  • 空调开启 → 自动关闭窗帘(避免冷气流失)
  • 空调关闭 → 自动打开窗帘
  • 窗帘关闭 → 自动开灯(补充采光)
  • 窗帘打开 → 自动关灯(自然光足够)

注意:联动可能产生连锁反应。例如开启空调 → 关闭窗帘 → 开灯。同一设备在同一次连锁中状态只改变一次,避免循环触发。

输入描述:第一行包含三个字符串,分别是灯、窗帘、空调的名称,用空格分隔。第二行包含三个字符串,分别是灯、窗帘、空调的初始状态(on 或 off),用空格分隔。接下来每行包含一个操作,格式为设备名 操作(操作为 on 或 off),直到输入结束。

输出描述:对于每个操作,按联动触发顺序输出每个状态发生变化的设备,格式为设备名 on 或设备名 off。若操作未导致状态变化(设备已在目标状态),则不输出。

输入示例

Light Curtain AC off on off AC on AC off Curtain off

输出示例

AC on Curtain off Light on AC off Curtain on Light off Curtain off Light on

解题思路:本题的核心是中介者模式的连锁反应机制。

角色对应

  • Mediator(抽象中介者)Mediator接口,定义send方法
  • ConcreteMediator(具体中介者)SmartHomeMediator,实现联动规则(空调→窗帘→灯)
  • Colleague(抽象同事类)Device抽象类,持有中介者引用,提供sendreceive方法
  • ConcreteColleague(具体同事类)LightCurtainAC,具体设备实现

连锁反应机制

  1. 用户操作设备(如开启空调)→ 调用device.send("on")
  2. send方法更新状态并输出,然后通知中介者mediator.send("on", this)
  3. 中介者根据联动规则,调用相关设备的receive方法(如关闭窗帘)
  4. receive方法更新状态并输出,再次通知中介者,形成递归连锁
  5. 避免循环触发:在sendreceive中检查if (!status.equals(message)),如果状态已经是目标状态则不处理
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String line = sc.nextLine(); String[] names = line.split(" "); line = sc.nextLine(); String[] status = line.split(" "); Mediator mediator = new SmartHomeMediator(); Light light = new Light(mediator, names[0], status[0]); Curtain curtain = new Curtain(mediator, names[1], status[1]); AC ac = new AC(mediator, names[2], status[2]); mediator.setLight(light); mediator.setCurtain(curtain); mediator.setAc(ac); Map<String, Device> map = new HashMap<>(); map.put(names[0], light); map.put(names[1], curtain); map.put(names[2], ac); while (sc.hasNext()) { String name = sc.next(); String s = sc.next(); Device d = map.get(name); d.send(s); } } } // 抽象中介者 interface Mediator { public void send(String message, Device device); } // 具体中介者:智能家居中控 class SmartHomeMediator implements Mediator { private Light light; private Curtain curtain; private AC ac; public void setLight(Light light) { this.light = light; } public void setCurtain(Curtain curtain) { this.curtain = curtain; } public void setAc(AC ac) { this.ac = ac; } public void send(String message, Device device) { // 空调状态变化触发窗帘联动 if (device instanceof AC) { if (message.equals("on")) { curtain.receive("off"); // 规则1:空调开 → 关窗帘 } else { curtain.receive("on"); // 规则2:空调关 → 开窗帘 } } // 窗帘状态变化触发灯联动 else if (device instanceof Curtain) { if (message.equals("on")) { light.receive("off"); // 规则4:窗帘开 → 关灯 } else { light.receive("on"); // 规则3:窗帘关 → 开灯 } } // 灯状态变化不触发联动 } } // 抽象同事类:设备基类 abstract class Device { protected Mediator mediator; protected String name; protected String status; public Device(Mediator mediator, String name, String status) { this.mediator = mediator; this.name = name; this.status = status; } public String getName() { return name; } public String getStatus() { return status; } // 用户操作触发状态变化 public void send(String message) { if (!status.equals(message)) { System.out.println(name + " " + message); status = message; mediator.send(message, this); // 通知中介者 } } // 中介者通知触发状态变化 public void receive(String message) { if (!status.equals(message)) { System.out.println(name + " " + message); status = message; mediator.send(message, this); // 状态变化后通知中介者,形成连锁 } } } // 具体同事类:灯 class Light extends Device { public Light(Mediator mediator, String name, String status) { super(mediator, name, status); } } // 具体同事类:窗帘 class Curtain extends Device { public Curtain(Mediator mediator, String name, String status) { super(mediator, name, status); } } // 具体同事类:空调 class AC extends Device { public AC(Mediator mediator, String name, String status) { super(mediator, name, status); } }
http://www.jsqmd.com/news/1139689/

相关文章:

  • 心电信号图神经网络论文分享(1)——MSAGFN多尺度双图融合
  • SecureCRT 7.0密码解密实战:逆向分析与Python脚本实现
  • 告别氟苯尼考检测“踩坑”!这款专属快检卡,为全产业链筑牢食安防线
  • AI算力基建动态简报(2026.07.06)
  • 影刀RPA新手教程:流程调试进阶完全指南——断点调试、日志分析与性能瓶颈定位
  • 许可证增购申请总被卡,管理层最想先看哪几项数据
  • Monaspace字体深度实战:编程字体革命与高效配置指南
  • SQL盲注实战指南:从布尔与时间盲注原理到DVWA靶场攻防
  • LTC6904与PIC24FJ256GB110构建高精度方波发生器方案
  • python6.7-函数的不定长参数
  • Blender 5.1.1中文版安装与Python 3.13工作流配置指南
  • (含安装包)小白零基础 Windows 安装 OpenClaw,全程可视化操作,附最新安装包
  • openEuler WSL 开发者指南:在 Windows 上搭建完整的 openEuler 开发环境
  • Grafana Dashboard 配置
  • HTTPS 粗解:证书、TLS 握手与对后端配置的影响
  • RowHammer防御机制中的时序侧信道漏洞:从DRAM物理原理到信息泄露
  • 戈壁自驾游备用电机携带与应急方案指南
  • 应对Go代码逆向工程挑战的garble深度解析:现代企业级应用安全加固方案
  • Codeforces Round 235 D. Roman and Numbers
  • 餐桌上的“隐形增效剂”:一文读懂甲氧苄啶的安全逻辑与快检科普
  • SSRF漏洞深度解析:原理、利用、绕过与纵深防御实战
  • 解决文件正在使用无法删除,顽固文件清理工具超好用
  • 计算机毕业设计之基于Web技术的测试管理工具设计与实现
  • 抖音无水印下载终极指南:简单三步搞定批量下载
  • 晨控CK-FR101ANS与松下FP0H系列PLC配置EtherNet/IP通讯连接手册
  • 【Azure Services Platform Step by Step-第13篇】在Windows Azure中使用PHP
  • Cadence Allegro 17.4 差分对设置:CM约束管理器 Electrical vs Physical 3大核心差异详解
  • 2026大容量破壁机冷热双用,3-6人使用刚刚好
  • 大模型破解医疗数据困境:从非结构化文本到可计算知识
  • 当40岁失业门将沃齐尼亚扑出梅西4次必进球,我悟了:这就是Hermes Agent 自进化架构的终极形态