一、观察者模式介绍

观察者模式(Observer Design Pattern)
观察者模式的定义如下:
在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象会自动收到通知。
观察者模式通常有两种对象角色:观察者别观察者
简单来理解观察者模式,被观察者 持有 观察者 的对象实例,当被观察者 执行了某项操作后,会分别调用持有的观察者 的处理方法,从而达到观察者观察,被观察者通知的效果。
按照观察者模型定义,很多类型都可以认为是观察者模式,如:发布订阅、观察者-被观察者,生产者-消费者,事件监听-事件发布。
在观察者模式的使用上,观察者模式可以分为两种:同步阻塞 和 异步非阻塞。
同步阻塞:整个通知流程,通知到了所有观察者才算结束。
异步非阻塞:将通知的操作给另外一个线程进行处理,当前线程直接结束。

二、观察者模式模板

业务场景,用户进行注册后的操作:
1、初始化钱包数据
2、发送注册成功通知
……
通过观察者模式来实现

观察者模式的实现要点:

  • 观察者角色
  • 被观察者角色
  • 被观察者持有观察者对象实例

2.1、高耦合观察者模式

2.1.1、被观察者 RegisterService

RegisterService 实现了注册的功能代码 ,同时也是一个被观察者,代码如下:
[设计模式]-[行为型]-观察者-介绍及应用 - 图1

在上述代码中,RegisterService 注册服务本身就是一个被观察者,同时持有了多个观察者的引用实例,在调用注册功能 register() 后,逐个通知观察者。

2.1.2、观察者

针对观察者,定义统一的接口 Observer 用来规范接口调用,相关的观察者代码如下:
[设计模式]-[行为型]-观察者-介绍及应用 - 图2

如上述代码,实现了钱包数据初始化消息通知初始化的观察者实现

后期拓展中,如果新增了积分数据,推荐链关系维护等业务逻辑,可以实现 Observer 实现新的观察者,同时注册到被观察者 RegisterService 注册代码中。

2.2、低耦合观察者模式

**

在实际项目开发中,通常会使用 springframework 组件 此时可以借助 springframework 中提供的 Event-Listener 来实现观察者模式。 而针对时间 Event 的发送,springframework提供了 ApplicationEventMulticaster 类作为事件发射器。

高耦合版观察者模式的实现是将整个注册服务代码实现 RegisterService 当成是一个被观察者,不过无形中将功能代码和业务代码进行了耦合。
通过 springframework Event-Listener 进行代码解耦,由 ApplicationEventMulticaster 发射器进行中转,整个操作中,Event充当被观察者,Listener 充当观察者。

2.2.1、被观察者 和 观察者

相关实现代码如下:
[设计模式]-[行为型]-观察者-介绍及应用 - 图3
其中 RegisterSuccessEvent 是事件源,也是被观察者,
RegistInitWalletDataListener 钱包数据初始化 ,RegistMessageNotifyListener 消息通知是监听器 也是观察者。

2.2.2、结合 IOC 容器,注册功能结合观察者模式

相关代码实现如下:
[设计模式]-[行为型]-观察者-介绍及应用 - 图4

当触发注册功能时,发送注册事件,相关的监听器监听到事件,然后进行处理。

2.2.3、单纯 API,注册功能集合观察者模式

单纯代码调用如下:
[设计模式]-[行为型]-观察者-介绍及应用 - 图5
在使用过程中,同样的需要把所有的监听器注册到 ApplicationEventMulticaster 发射器中

感兴趣的可以看源码, ApplicationEventMulticaster#multicastEvent 的实现,一样是,通过遍历注册的 Listener 调用其 Listener#onApplication 实现的通知。

三、Spring Boot 中观察者模式

在 Spring Boot 引导类 SpringApplicationrun 方法中存在如下代码:

[设计模式]-[行为型]-观察者-介绍及应用 - 图6
关注 SpringApplication#run 中的 SpringApplicationRunListeners ,部分代码如下

[设计模式]-[行为型]-观察者-介绍及应用 - 图7

上述代码关注 List<SpringApplicationRunListener> ,所有的方法都是围绕该List列表来执行的,来看一下 SpringApplicationRunListener 的实现类 EventPublishingRunListener,相关代码如下
[设计模式]-[行为型]-观察者-介绍及应用 - 图8

如图,SpringBoot 借助事件发射器进行事件的推送,触发监听监听器的调用,从而实现配置加载初始化等操作的实现。


【公众号】花好夜猿
wxlogo.jpg