一. 前言
我在spring篇,介绍过ApplicationListener,接收到spring的一些事件,就会触发相应的通知操作。这是典型的发布订阅模式,也就是观察者模式。
说到发布订阅,大家还会想到MQ,Zookeeper等,这些很许多事件监听,也是观察者模式的一种体现。
本文中,我们来讨论下如何实现这一模式。
二. 模型抽象
2.1 观察者模式的主要角色
- 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
- 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
- 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
- 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
2.2 结构模型抽象

观察者模式的结构图
2.3 代码实现
- 主题抽象
public interface Subject {
// 添加订阅关系
void attach(Observer observer);
// 移除订阅关系
void detach(Observer observer);
// 通知订阅者
void notifyObservers(String message);
}
- 具象实现
也就是具体事件的订阅与通知
public class ConcreteSubject implements Subject {
// 订阅者容器
private List<Observer> observers = new ArrayList<Observer>();
/**
* 增加观察者
*
* @param observer
*/
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String message) {
// 通知订阅者们
for (Observer observer : observers) {
observer.response(message);
}
}
}
- 观察者抽象
public interface Observer {
// 接收推送消息,处理业务逻辑
void response(String message);
}
- 具体订阅者处理通知
public class ConcreteObserver implements Observer {
@Override
public void response(String message) {
//接收到主题推送消息,做具体业务处理
System.out.println("具体的观察者收到了具体主题推送的消息: " + message);
}
}
至此,我们就有了发布订阅模型,该模式重点是抽象,也就是面向接口编程,实现了业务的解耦。