什么是观察者设计模式?
什么是观察者
观察者模式的主要角色包括:
-
主题(Subject): 也称为被观察者或可观察对象。它维护了一系列观察者对象,并提供方法用于注册、删除和通知观察者。当主题的状态发生改变时,它会通知所有注册的观察者。
-
观察者(Observer): 观察主题的对象。观察者定义了一个更新方法,主题在状态改变时会调用这个方法来通知观察者。观察者可以根据主题的通知来执行相应的操作。
观察者的应用
观察者模式在实际应用中经常用于处理事件驱动的编程场景,如图形用户界面(GUI)开发、消息传递系统等。通过观察者模式,可以实现对象之间的解耦,提高系统的灵活性和可维护性。
在Spring Framework
中,观察者模式的应用非常广泛,尤其在Spring的事件驱动机制中。Spring的事件机制允许对象在特定事件发生时发布事件,并允许其他对象注册为监听器以接收这些事件。这与观察者模式的概念非常相似,其中事件源就是观察者模式中的主题,而事件监听器就是观察者。
应用程序事件: Spring允许应用程序发布自定义事件,并提供了ApplicationEvent和ApplicationListener接口。应用程序可以创建自定义事件类,并在需要时发布这些事件。其他对象可以实现ApplicationListener接口并注册为监听器,以接收并处理这些事件。
Spring MVC事件: 在Spring MVC中,可以使用 ApplicationEventPublisher
接口发布自定义事件,并通过@EventListener注解或实现 ApplicationListener
接口的方式来处理这些事件。这使得在MVC架构中进行解耦和处理事件变得更加容易。
如何实现
日常中比较经典的实例场景 , 举个例子,如博客园的文章订阅, 当关注的作者发布了新的文章后,关注其的粉丝就会收到消息通知,这里将代码拆出来如下。
import java.util.ArrayList;
import java.util.List;
// 主题接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers(String news);
}
// 观察者接口
interface Observer {
void update(String news);
}
// 新闻发布者
class NewsPublisher implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String news) {
for (Observer observer : observers) {
observer.update(news);
}
}
public void publishNews(String news) {
System.out.println("发布新闻: " + news);
notifyObservers(news);
}
}
// 观察者 - 读者
class Reader implements Observer {
private String name;
public Reader(String name) {
this.name = name;
}
@Override
public void update(String news) {
System.out.println(name + " 收到新闻: " + news);
}
}
public class ObserverPatternExample {
// 创建新闻发布者
NewsPublisher publisher = new NewsPublisher();
// 创建两个观察者(读者)
Observer reader1 = new Reader("小明");
Observer reader2 = new Reader("小红");
// 注册观察者
publisher.registerObserver(reader1);
publisher.registerObserver(reader2);
// 发布新闻
publisher.publishNews("Java 21发布了!");
publisher.publishNews("Spring Framework 更新了!");
// 读者取消订阅
publisher.removeObserver(reader2);
// 再次发布新闻
publisher.publishNews("小米 su7 上线了,雷总为你开车门,快行动起来吧!");
}
}
程序运行日志如下
发布新闻: Java 21发布了!
小明 收到新闻: Java 21发布了!
小红 收到新闻: Java 21发布了!
发布新闻: Spring Framework 更新了!
小明 收到新闻: Spring Framework 更新了!
小红 收到新闻: Spring Framework 更新了!
发布新闻: 小米 su7 上线了,雷总为你开车门,快行动起来吧!
小明 收到新闻: 小米 su7 上线了,雷总为你开车门,快行动起来吧!
结语
这里介绍观察者,是希望从易于理解的概念开始对 Reactive Programing
的理解,在响应式编程中多数基于观察者模式思想演变而来,如在 Reactor 中,订阅者(Subscriber)订阅了数据流(Publisher),并在数据流中的元素发生变化时接收通知。
通知机制: 在观察者模式中,主题状态的变化会触发通知,通知会被发送给所有注册的观察者。在Reactor中,数据流中的元素发生变化时会触发通知,通知会被发送给所有订阅了该数据流的订阅者。
事件驱动编程: 观察者模式和 Reactor 都支持事件驱动的编程模型。在观察者模式中,事件源(主题)发生事件(状态变化),并通知观察者。在 Reactor 中,事件(数据元素)在流中传递,并且订阅者可以对这些事件进行响应式地处理。