news 2026/7/7 6:55:46

相似模式区分

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
相似模式区分

总览

模式核心意图典型场景
中介者协调多个对象间的复杂交互智能家居中控、聊天室、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); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 6:55:09

如何实现智能网页资源批量下载:自动化工具实战指南

如何实现智能网页资源批量下载&#xff1a;自动化工具实战指南 【免费下载链接】ResourcesSaverExt Chrome Extension for one click downloading all resources files and keeping folder structures. 项目地址: https://gitcode.com/gh_mirrors/re/ResourcesSaverExt …

作者头像 李华
网站建设 2026/7/7 6:51:25

2026大容量破壁机冷热双用,3-6人使用刚刚好

2026大容量破壁机冷热双用&#xff0c;3-6人使用刚刚好 清晨六点半&#xff0c;厨房里飘出浓郁的黑芝麻糊香气&#xff0c;玻璃杯壁上挂着绵密的豆浆泡沫&#xff0c;旁边保温杯里装着给孩子的南瓜米糊。对于三口之家乃至六口大家庭来说&#xff0c;一台靠谱的破壁机几乎承包了…

作者头像 李华
网站建设 2026/7/7 6:50:31

遗忘之海在模拟器上怎么玩?遗忘之海电脑版游玩方法教程

《遗忘之海》融合奇幻航海、肉鸽轮回、舰船海战、陆地回合闯关多重内容&#xff0c;广阔全域海域搭配随机海岛奇遇、动态天气光影&#xff0c;单局出海探索流程耗时较长&#xff0c;大量舰船养成、藏品收集内容需要长时间在线操作。很多玩家习惯手机游玩后&#xff0c;常会遇到…

作者头像 李华
网站建设 2026/7/7 6:46:26

LTC6904与PIC24FJ256GB110构建高精度方波发生器方案

1. 项目背景与核心价值在嵌入式系统开发中&#xff0c;精确的时钟信号就像交响乐团的指挥家——它决定了整个系统的节奏和协调性。LTC6904这颗来自ADI的低功耗可编程振荡器芯片&#xff0c;配合PIC24FJ256GB110微控制器的强大处理能力&#xff0c;可以构建出频率精度达0.5%的方…

作者头像 李华