观察者模式的定义
观察者模式是一种行为设计模式,定义了一种 一对多 的依赖关系:
- 一个对象(被观察者,
Subject)的状态发生改变时,多个依赖对象(观察者,Observer)都会收到通知,并自动更新。
观察者模式的结构
观察者模式的核心结构包括以下几部分:
- 被观察者(Subject):
- 管理观察者列表。
- 提供方法让观察者注册和注销。
- 负责在自身状态变化时通知所有观察者。
- 观察者(Observer):
- 订阅被观察者以接收更新。
- 定义一个接口,通常只包含一个方法(比如
update),用来响应被观察者的通知。
- 具体被观察者(ConcreteSubject):
- 实现被观察者接口,管理具体的状态。
- 当状态变化时,通知所有观察者。
- 具体观察者(ConcreteObserver):
- 实现观察者接口,接收并处理被观察者的通知。
观察者模式的类图
+------------------+ 1 +------------------+
| Subject |--------------| Observer |
+------------------+ depends on +------------------+
| + attach(o) | | + update() |
| + detach(o) | | |
| + notify() | | |
+------------------+ +------------------+
^ ^
| |
| |
+------------------+ +-----------------------+
| ConcreteSubject | | ConcreteObserver |
+------------------+ +-----------------------+
| + state | | + update() |
| + getState() | | + show updated data |
| + setState() | +-----------------------+
+------------------+观察者模式的优点
- 解耦:观察者和被观察者是松耦合的。被观察者只负责通知,不关心具体观察者的实现。
- 扩展性强:可以动态增加或移除观察者,而无需修改被观察者的代码。
- 自动更新:观察者自动感知被观察者的变化,无需主动轮询。
观察者模式的缺点
- 性能问题:当观察者过多时,通知所有观察者可能会带来性能开销。
- 可能导致循环依赖:如果观察者反过来修改被观察者的状态,可能导致死循环。
实现一个观察者模式的 Demo
场景:
模拟一个新闻发布系统:
- 有一个新闻发布者(
NewsPublisher),它会发布新闻。 - 有多个订阅者(
Subscriber),会收到新闻发布者的通知。
代码实现
// 被观察对象(Subject)
class NewsPublisher {
// 保存所有订阅者
private val subscribers = mutableListOf<Subscriber>()
// 添加订阅者
fun subscribe(subscriber: Subscriber) {
subscribers.add(subscriber)
}
// 移除订阅者
fun unsubscribe(subscriber: Subscriber) {
subscribers.remove(subscriber)
}
// 发布新闻,通知所有订阅者
fun publish(news: String) {
for (subscriber in subscribers) {
subscriber.update(news) // 通知订阅者
}
}
}
// 观察者(Subscriber 接口)
interface Subscriber {
fun update(news: String) // 当有新闻时,会触发该方法
}
// 具体的观察者 A
class EmailSubscriber(private val name: String) : Subscriber {
override fun update(news: String) {
println("$name 收到了新闻:$news")
}
}
// 具体的观察者 B
class SmsSubscriber(private val phoneNumber: String) : Subscriber {
override fun update(news: String) {
println("短信 $phoneNumber 收到了新闻:$news")
}
}
// 主函数模拟
fun main() {
// 创建新闻发布者
val newsPublisher = NewsPublisher()
// 创建订阅者
val emailSubscriber = EmailSubscriber("Alice")
val smsSubscriber = SmsSubscriber("1234567890")
// 订阅新闻
newsPublisher.subscribe(emailSubscriber)
newsPublisher.subscribe(smsSubscriber)
// 发布新闻
newsPublisher.publish("《观察者模式入门》已经上线啦!")
newsPublisher.publish("第二条新闻:Kotlin 是不是很好用?")
// 取消订阅
newsPublisher.unsubscribe(emailSubscriber)
// 再次发布新闻
newsPublisher.publish("只有短信订阅者会收到这条新闻!")
}观察者模式在 Android 中的应用
LiveData- 被观察者:
LiveData。 - 观察者: Activity 或 Fragment 中注册的
Observer。 - 当
LiveData的值变化时,UI 自动更新。
- 被观察者:
BroadcastReceiver- 被观察者: 系统广播(
Intent)。 - 观察者: 注册的
BroadcastReceiver。
- 被观察者: 系统广播(
RecyclerView** 的数据绑定**- 被观察者: 数据源(如
List)。 - 观察者: RecyclerView 的
Adapter。
- 被观察者: 数据源(如
核心思想:“事件驱动的自动通知机制”
更新: 2025-03-24 13:20:00
原文: https://www.yuque.com/dongpozhouzi-mshe3/zhm85g/fhnr325z5yitvld7