观察者模式的定义

观察者模式是一种行为设计模式,定义了一种 一对多 的依赖关系:

  • 一个对象(被观察者,Subject)的状态发生改变时,多个依赖对象(观察者,Observer)都会收到通知,并自动更新。

观察者模式的结构

观察者模式的核心结构包括以下几部分:

  1. 被观察者(Subject):
    • 管理观察者列表。
    • 提供方法让观察者注册和注销。
    • 负责在自身状态变化时通知所有观察者。
  2. 观察者(Observer):
    • 订阅被观察者以接收更新。
    • 定义一个接口,通常只包含一个方法(比如update),用来响应被观察者的通知。
  3. 具体被观察者(ConcreteSubject):
    • 实现被观察者接口,管理具体的状态。
    • 当状态变化时,通知所有观察者。
  4. 具体观察者(ConcreteObserver):
    • 实现观察者接口,接收并处理被观察者的通知。

观察者模式的类图

+------------------+      1       +------------------+
|     Subject      |--------------|     Observer     |
+------------------+  depends on  +------------------+
| + attach(o)      |              | + update()       |
| + detach(o)      |              |                  |
| + notify()       |              |                  |
+------------------+              +------------------+
         ^                                ^
         |                                |
         |                                |
+------------------+           +-----------------------+
| ConcreteSubject  |           |  ConcreteObserver     |
+------------------+           +-----------------------+
| + state          |           | + update()            |
| + getState()     |           | + show updated data   |
| + setState()     |           +-----------------------+
+------------------+

观察者模式的优点

  1. 解耦:观察者和被观察者是松耦合的。被观察者只负责通知,不关心具体观察者的实现。
  2. 扩展性强:可以动态增加或移除观察者,而无需修改被观察者的代码。
  3. 自动更新:观察者自动感知被观察者的变化,无需主动轮询。

观察者模式的缺点

  1. 性能问题:当观察者过多时,通知所有观察者可能会带来性能开销。
  2. 可能导致循环依赖:如果观察者反过来修改被观察者的状态,可能导致死循环。

实现一个观察者模式的 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 中的应用

  1. LiveData
    • 被观察者:LiveData
    • 观察者: Activity 或 Fragment 中注册的 Observer
    • LiveData 的值变化时,UI 自动更新。
  2. BroadcastReceiver
    • 被观察者: 系统广播(Intent)。
    • 观察者: 注册的 BroadcastReceiver
  3. RecyclerView** 的数据绑定**
    • 被观察者: 数据源(如 List)。
    • 观察者: RecyclerView 的 Adapter

核心思想:“事件驱动的自动通知机制”

更新: 2025-03-24 13:20:00
原文: https://www.yuque.com/dongpozhouzi-mshe3/zhm85g/fhnr325z5yitvld7


相关笔记