最后更新:2026-11-01 · 基于第 1 次作答
结论:用观察者模式——天气数据作为 Subject,通知服务与行程推荐服务作为 Observer,天气变化时统一通知所有订阅者;推荐算法再用策略模式按用户/场景选择。 关键词:Observer 解耦 · Subject/Observer · Strategy 选策略 边界:观察者适合"一对多、事件驱动";若仅单一固定反应或需强顺序强一致,观察者可能过度设计。
核心考点定位:考察"事件驱动的一对多通知"选型与"算法可替换"的组合能力;面试官想看到解耦收益与失败路径,而非只背模式名。
机制链(≥3 环):
notifyObservers() 遍历注册的 Observer → 各 Observer 的 update() 被触发 → 通知与推荐解耦。证据锚点:
Observer:观察者接口(update())Subject:被观察者(注册表)notifyObservers:统一通知入口registerObserver / unregisterObserver:运行期订阅管理Strategy:算法族抽象接口Context:持策略引用、运行时切换Kafka / 消息队列:跨服务异步解耦@EventListener:Spring 事件监听(观察者落地)ApplicationEventPublisher:Spring 事件发布入口对比与权衡:
| 方案 | 耦合 | 扩展性 | 失败隔离 | 适用 |
|---|---|---|---|---|
| 直接 if-else 通知 | 高 | 差 | 无 | 少渠道、固定 |
| 观察者模式 | 低 | 好(动态增删) | 需逐 Observer 隔离 | 一对多事件 |
| 事件总线 / 发布订阅 | 低 | 好(异步) | 好(消息队列) | 跨服务、异步 |
| 策略模式(推荐算法) | 低 | 好 | 无 | 算法可替换 |
常见误区:
适用边界:
ApplicationEventPublisher/@EventListener 是观察者模式的框架化落地,跨服务再升级到消息队列。【结论】 用观察者模式:天气数据作为被观察者,通知服务与推荐行程作为观察者,天气变化时统一通知;推荐算法再用策略模式按用户/场景选择。
【三点】
第一,观察者解耦:天气数据类不依赖具体通知渠道,新增渠道只需注册观察者,符合开闭原则。
第二,策略选算法:推荐行程算法抽象为策略接口,运行期按用户偏好/天气场景切换,避免 if-else 分支爆炸。
第三,失败隔离:逐观察者 try-catch + 重试/降级,防止单个通知失败拖垮整条链路;通知渠道在运行期动态增删,新增不改天气数据类。
【边界】 观察者适合"一对多、动态订阅";若仅单一固定反应或需强顺序强一致,观察者可能过度设计,可改用事件总线/显式串行化;策略模式不要为少量固定分支过度抽象;链路跨服务、需可靠投递时升级到消息队列,代价是引入中间件与最终一致。
题目:天气预报变化触发用户通知和推荐行程,用什么设计模式?
难度:high
标签:design-pattern/observer, design-pattern/strategy, general/knowledge, difficulty/high
评分:⭐⭐⭐⭐☆(4/5)
天气预报变化可以做一个观察者模式,观察天气预报的变动,如果有变动就触发下一阶段执行的操作,对应设定一个策略模式,对不同的添加推送不同的行程
评分:⭐⭐⭐⭐☆(4/5)
优点:正确定位观察者模式(天气变化 → 触发下游通知/推荐)+ 策略模式(对不同场景选不同推送/行程)。选型正确、有组合意识。
不足:没展开解耦收益(天气源与通知/推荐解耦,增删观察者不动源)、观察者的推/拉模型、策略与模板方法/简单工厂的区别、以及"什么时候观察者会过度设计"。
补充:补①观察者的解耦与开闭原则;②推/拉模型;③回调异常隔离与重试降级;④策略 vs 模板方法;⑤过度设计的边界。
完整讲解见上方「完整讲解(权威版)」