一、观察者模式介绍
观察者模式(Observer Design Pattern)。
观察者模式的定义如下:
在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象会自动收到通知。
观察者模式通常有两种对象角色:观察者 和 别观察者
简单来理解观察者模式,被观察者 持有 观察者 的对象实例,当被观察者 执行了某项操作后,会分别调用持有的观察者 的处理方法,从而达到观察者观察,被观察者通知的效果。
按照观察者模型定义,很多类型都可以认为是观察者模式,如:发布订阅、观察者-被观察者,生产者-消费者,事件监听-事件发布。
在观察者模式的使用上,观察者模式可以分为两种:同步阻塞 和 异步非阻塞。
同步阻塞:整个通知流程,通知到了所有观察者才算结束。
异步非阻塞:将通知的操作给另外一个线程进行处理,当前线程直接结束。
二、观察者模式模板
业务场景,用户进行注册后的操作:
1、初始化钱包数据
2、发送注册成功通知
……
通过观察者模式来实现
观察者模式的实现要点:
- 观察者角色
- 被观察者角色
- 被观察者持有观察者对象实例
2.1、高耦合观察者模式
2.1.1、被观察者 RegisterService
RegisterService 实现了注册的功能代码 ,同时也是一个被观察者,代码如下:![[设计模式]-[行为型]-观察者-介绍及应用 - 图1](/uploads/projects/it-learn@java-base/dd5a3d4bb4b25c1bc7c6230032b1b121.webp)
在上述代码中,RegisterService 注册服务本身就是一个被观察者,同时持有了多个观察者的引用实例,在调用注册功能 register() 后,逐个通知观察者。
2.1.2、观察者
针对观察者,定义统一的接口 Observer 用来规范接口调用,相关的观察者代码如下:![[设计模式]-[行为型]-观察者-介绍及应用 - 图2](/uploads/projects/it-learn@java-base/0d5296a0f70d9116359a8297aeba39ca.webp)
如上述代码,实现了钱包数据初始化和消息通知初始化的观察者实现
后期拓展中,如果新增了积分数据,推荐链关系维护等业务逻辑,可以实现 Observer 实现新的观察者,同时注册到被观察者 RegisterService 注册代码中。
2.2、低耦合观察者模式
**
在实际项目开发中,通常会使用
springframework组件 此时可以借助 springframework 中提供的Event-Listener来实现观察者模式。 而针对时间Event的发送,springframework提供了 ApplicationEventMulticaster 类作为事件发射器。
高耦合版观察者模式的实现是将整个注册服务代码实现 RegisterService 当成是一个被观察者,不过无形中将功能代码和业务代码进行了耦合。
通过 springframework Event-Listener 进行代码解耦,由 ApplicationEventMulticaster 发射器进行中转,整个操作中,Event充当被观察者,Listener 充当观察者。
2.2.1、被观察者 和 观察者
相关实现代码如下:![[设计模式]-[行为型]-观察者-介绍及应用 - 图3](/uploads/projects/it-learn@java-base/d6db6d79e1b2367c384a1a3938398036.webp)
其中 RegisterSuccessEvent 是事件源,也是被观察者,RegistInitWalletDataListener 钱包数据初始化 ,RegistMessageNotifyListener 消息通知是监听器 也是观察者。
2.2.2、结合 IOC 容器,注册功能结合观察者模式
相关代码实现如下:![[设计模式]-[行为型]-观察者-介绍及应用 - 图4](/uploads/projects/it-learn@java-base/c8732191b2d728fdcb3484bccc7ce694.webp)
当触发注册功能时,发送注册事件,相关的监听器监听到事件,然后进行处理。
2.2.3、单纯 API,注册功能集合观察者模式
单纯代码调用如下:![[设计模式]-[行为型]-观察者-介绍及应用 - 图5](/uploads/projects/it-learn@java-base/8aa7140601cd0e607693d1be94170b26.webp)
在使用过程中,同样的需要把所有的监听器注册到 ApplicationEventMulticaster 发射器中
感兴趣的可以看源码,
ApplicationEventMulticaster#multicastEvent的实现,一样是,通过遍历注册的Listener调用其Listener#onApplication实现的通知。
三、Spring Boot 中观察者模式
在 Spring Boot 引导类 SpringApplication 的 run 方法中存在如下代码:
![[设计模式]-[行为型]-观察者-介绍及应用 - 图6](/uploads/projects/it-learn@java-base/5f6f6d28bb1114118982f2269d9269c7.webp)
关注 SpringApplication#run 中的 SpringApplicationRunListeners ,部分代码如下
![[设计模式]-[行为型]-观察者-介绍及应用 - 图7](/uploads/projects/it-learn@java-base/2d9f521893e68ec41dea14750f57df7a.webp)
上述代码关注 List<SpringApplicationRunListener> ,所有的方法都是围绕该List列表来执行的,来看一下 SpringApplicationRunListener 的实现类 EventPublishingRunListener,相关代码如下![[设计模式]-[行为型]-观察者-介绍及应用 - 图8](/uploads/projects/it-learn@java-base/1fb32306c4825b0caa6001d484ed39be.webp)
如图,SpringBoot 借助事件发射器进行事件的推送,触发监听监听器的调用,从而实现配置加载初始化等操作的实现。
【公众号】花好夜猿
