行为型 简单
观察者模式
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