回复
Guava、Spring 如何抽象观察者模式?(一)
Handpc
发布于 2022-6-23 17:07
浏览
0收藏
前言
《设计模式实战》系列目前已经写了 7 篇了,最近几篇平均阅读保持 1.1k+,后面也会延续之前的高质量,欢迎继续关注
- 【设计模式实战】策略模式
- 【设计模式实战】责任链模式
- 【设计模式实战】Builder 模式
- 【设计模式实战】代理模式
- 【设计模式实战】模版方法模式
- 【设计模式实战】适配器模式
- 【设计模式实战】...
今天讲解一篇行为型设计模式,什么是行为型?行为型主要负责设计 类或对象之间的交互。工作中常用的观察者模式就是一种行为型设计模式
最近在尝试重构之前写过的代码。在重新梳理过业务之后,发现已有的设计场景应该能够接入到设计模式,而且查看了代码的提交记录,更是坚定了此想法
保持之前的一贯作风,想要说明一个设计模式,需要三板斧支撑。什么是观察者模式?如何使用观察者模式?项目中应该如何应用?
观察者设计模式大纲如下:
- 什么是观察者模式
- 观察者模式代码如何写
- 如何使用观察者模式结合业务
- Guava EventBus 观察者模式
- Spring ApplicationEvent 事件模型
- 观察者模式最后的总结
什么是观察者模式
观察者模式 是一种行为设计模式,允许定义一种订阅通知机制,可以在对象(被观察者)事件发生时通知多个 “观察” 该对象的观察者对象,所以也被称为 发布订阅模式
其实我个人而言,不太喜欢使用文字去定义一种设计模式的语义,因为这样总是难以理解。所以就有了下面生活中的例子,来帮助读者更好的去理解模式的语义。类图如下所示:
在举例说明前,先让我们熟悉下观察者模式中的 角色类型 以及代码示例。观察者模式由以下几部分角色组成,可以参考代码示例去理解,不要被文字描述带偏
- 主题(被观察者)(Subject):抽象主题角色把所有观察者对象保存在一个容器里,提供添加和移除观察者接口,并且提供出通知所有观察者对象接口(也有作者通过 Observable 描述)
- 具体主题(具体被观察者)(Concrete Subject):具体主题角色的职责就是实现抽象目标角色的接口语义,在被观察者状态更改时,给容器内所有注册观察者发送状态通知
public interface Subject { void register(Observer observer); // 添加观察者 void remove(Observer observer); // 移除观察者 void notify(String message); // 通知所有观察者事件 } public class ConcreteSubject implements Subject { private static final List<Observer> observers = new ArrayList(); @Override public void register(Observer observer) { observers.add(observer); } @Override public void remove(Observer observer) { observers.remove(observer); } @Override public void notify(String message) { observers.forEach(each -> each.update(message)); } }
- 抽象观察者(Observer):抽象观察者角色是观察者的行为抽象,它定义了一个修改接口,当被观察者发出事件时通知自己
- 具体观察者(Concrete Observer):实现抽象观察者定义的更新接口,可以在被观察者发出事件时通知自己
public interface Observer { void update(String message); // String 入参只是举例, 真实业务不会限制 } public class ConcreteObserverOne implements Observer { @Override public void update(String message) { // 执行 message 逻辑 System.out.println("接收到被观察者状态变更-1"); } } public class ConcreteObserverTwo implements Observer { @Override public void update(String message) { // 执行 message 逻辑 System.out.println("接收到被观察者状态变更-2"); } }
我们跑一下上面的观察者模式示例,如果不出意外的话会将两个观察者执行逻辑中的日志打印输出。如果是平常业务逻辑,抽象观察者定义的入参是具有业务意义的,大家可以类比项目上使用到的 MQ Message 机制
public class Example {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
subject.register(new ConcreteObserverOne());
subject.register(new ConcreteObserverTwo());
subject.notify("被观察者状态改变, 通知所有已注册观察者");
}
}
文章转自公众号:龙台的技术笔记
已于2022-6-23 17:07:55修改
赞
收藏
回复
相关推荐