流动的观察者模式 | Flutter 设计模式

本文探讨了观察者模式在Flutter、Dart语言中的实现和应用,包括ChangeNotifier、Navigator和Stream。观察者模式实现了发布订阅机制,使得组件能够响应状态变化。在Flutter中,ChangeNotifier用于状态管理,而Navigator的路由观察者可以监听用户行为。Dart的Stream提供了内置的观察者模式支持,用于异步操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。

这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己。

从定义中,不难发现,观察者被观察者 / 发布者 是这个模式中最重要的组成元素。

微信的公众号可以被视为生活中最典型的观察者模式的例子。如果你订阅了「Flutter社区」,每当 Flutter 社区发布文章时,就会给你及其他订阅者推送这个消息,这其中你就是 观察者,公众号「Flutter社区」就是 被观察者 (Observable) 或发布者 (Subject)

观察者模式经常被应用在这类事件处理系统中,从概念上理解,被观察者也经常被称作是 事件流 (stream of events) 或者说是 事件流的来源 (stream source of events),而观察者相当于 事件接收器 (sinks of events)

同时,观察者模式也是实现 响应式编程 的基础,RxDart、EventBus 等库都是观察者模式下的产物。

面向对象

面向对象中,观察者和和发布者 (被观察者) 分别对应两个类 (Observer 和 Subject) 的对象。

观察者模式 UML 图,图源维基百科

发布类 (Subject) 中通常会有提供给每个对象订阅或取消订阅发布者事件流的 订阅机制,包括:

  1. 一个用于存储订阅者对象引用的列表成员变量;

  2. 几个用于添加或删除该列表中订阅者的公有方法。

// 被观察者
class Subject {
  List<Observer> _observers;
  Subject([List<Observer> observers]) {
    _observers = observers ?? [];
  }

  // 注册观察者
  void registerObserver(Observer observer) {
    _observers.add(observer);
  }
  
  // 解注册观察者
  void unregisterObserver(Observer observer) {
    _observers.remove(observer)
  }

  // 通知观察者
  void notifyobservers(Notification notification) {
    for (var observer in _observers) {
      observer.notify(notification);
    }
  }
}

此时,每当事件发生,它只需遍历订阅者并调用其对象的特定通知方法即可 (如上面代码中的 notifyobservers 方法) 。

实际应用中,一个发布者通常会对应多个订阅者,且发布者与订阅者应当遵循面向对象的开发设计原则,因此:

  1. 为了避免耦合,订阅者们必须实现同样的接口;

  2. 发布者仅通过该接口与订阅者交互,接口方法可以声明参数, 这样发布者在发出通知时就能传递一些上下文数据 (如下面代码中的 notification 对象) 。

// 观察者
class Observer {
  String name;
  
  Observer(this.name);

  void notify(Notification notification) {
    print("[${notification.timestamp.toIso8601String()}] Hey $name, ${notification.message}!");
  }
}

这样,我们可以得出如下这样用 Dart 语言实现的观察者模式了,下面是一个简单的应用:

// 具体的被观察者 CoffeeMaker
// 每当 Coffee 制作完成发出通知给观察者。
class CoffeeMaker extends Subject {
  CoffeeMaker([List<Observer> observers]) : super(observers);
  
  void brew() {
    print("Br
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值