行为型 简单

观察者模式

Observer Pattern

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

概述

观察者模式是一种行为型设计模式,它允许你定义一个订阅机制,可以在对象事件发生时通知多个"观察"该对象的其他对象。

适用场景

  • 当一个对象的改变需要同时改变其他对象,而且不知道具体有多少对象有待改变时
  • 当一个对象必须通知其他对象,而它又不能假定其他对象是谁时
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时

优点

  • +开闭原则:无需修改发布者代码就能引入新的订阅者类
  • +可以在运行时建立对象之间的联系
  • +观察者和被观察者之间是抽象耦合的

缺点

  • 订阅者的通知顺序是随机的
  • 如果观察者和被观察者之间有循环依赖,可能导致系统崩溃
  • 如果观察者太多,通知所有观察者可能需要很多时间

结构

classDiagram class Subject { <<interface>> +attach(observer: Observer) +detach(observer: Observer) +notify() } class Observer { <<interface>> +update(subject: Subject) } class ConcreteSubject { -observers: Observer[] -state: any +attach(observer: Observer) +detach(observer: Observer) +notify() +getState() +setState(state) } class ConcreteObserver { -name: string +update(subject: Subject) } class Client { +main() } Subject <|.. ConcreteSubject : implements Observer <|.. ConcreteObserver : implements ConcreteSubject --> Observer : notifies ConcreteObserver --> Subject : observes Client ..> ConcreteSubject : creates Client ..> ConcreteObserver : creates style Subject fill:#e8f5e9,stroke:#388e3c,stroke-width:2px style Observer fill:#e8f5e9,stroke:#388e3c,stroke-width:2px style ConcreteSubject fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style ConcreteObserver fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style Client fill:#f5f5f5,stroke:#616161,stroke-width:1px

交互演示

观察订阅-发布机制如何工作
Subject
📰
State: idle
notify()
Observers
Observer 1
Observer 2

点击"更新状态"观察主题如何通知所有订阅的观察者

生活类比

观察者模式就像是现实世界中的订阅和通知系统

邮件订阅

你订阅了一个邮件列表,当有新文章发布时,所有订阅者都会收到邮件通知。

社交媒体

你关注了某个博主,当博主发布新内容时,你会收到推送通知。

代码实现

Example.java

实际应用

Java Event Handling

Java 的 Swing/AWT 事件处理机制就是观察者模式的典型应用。

Example.java

Vue.js 响应式系统

Vue 的响应式系统使用观察者模式来实现数据变化时自动更新视图。

Example.java

RxJS Observable

RxJS 库完全基于观察者模式,提供了丰富的操作符来处理异步数据流。

Example.java

Java PropertyChangeListener

JavaBeans 规范中的 PropertyChangeListener 是标准的观察者模式实现。

Example.java

练习

1

观察者模式定义了什么样的依赖关系?

2

推模型(Push Model)和拉模型(Pull Model)的主要区别是什么?

3

在使用智能指针实现观察者模式时,应该使用 weak_ptr 存储观察者以避免循环引用

4

以下哪个不是观察者模式的优点?