设计模式之观察者模式-谈谈你对观察者模式的理解
定义
先来段wiki上面的定义:观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。简单来讲,就是定义了一组一对多的关系。当被观察者的状态改变,会通知观察者做出相应的动作。
在开发过程中,常常会遇到如下的场景:
- 游戏开发中,当人物走到某个格子,触发加血、战斗等动作
- 微信公众号,当用户关注了某公众号,一旦公众号更新了文章,便可以给用户进行推送
在这种情况下,我们该如何实现符合开闭原则的代码呢,观察者模式便是一个很好的选择。
模式结构及实现
下图便是观察者模式的模式结构。
从图中可以看出,观察者模式主要结构主要包括发布者和订阅者两个行为对象,发布者持有所有订阅者的集合,当需要发布事件或者消息时,通知订阅者做出相应的动作。
代码
定义事件接口,作为观察者与被观察者之间交互的媒介
public interface Event {
}
定义Subscriber接口,作为观察者的接口
public interface Subscriber {
void update(Event event);
}
Subscriber的两个简单实现类
public class ReadSubscriber implements Subscriber{
@Override
public void update(Event e) {
System.out.println("ReadSubscriber");
}
}
public class WriteSubscriber implements Subscriber{
@Override
public void update(Event e) {
System.out.println("WriteSubscriber");
}
}
定义Publisher接口,作为被观察者的接口
public interface Publisher {
void subscribe(Subscriber subscriber);
void unsubscribe(Subscriber subscriber);
void notifySubscribers(Event event);
}
Publisher接口实现类
public class DefaultPublisher implements Publisher{
private final List<Subscriber> subscribers = new ArrayList<>();
@Override
public void subscribe(Subscriber subscriber) {
subscribers.add(subscriber);
}
@Override
public void unsubscribe(Subscriber subscriber) {
subscribers.remove(subscriber);
}
@Override
public void notifySubscribers(Event event) {
for(Subscriber subscriber:subscribers){
subscriber.update(event);
}
}
}
Demo测试
public class Demo {
public static void main(String[] args) {
DefaultPublisher defaultPublisher = new DefaultPublisher();
defaultPublisher.subscribe(new ReadSubscriber());
defaultPublisher.subscribe(new WriteSubscriber());
Event event = new Event() {
};
defaultPublisher.notifySubscribers(event);
}
}
结果
ReadSubscriber
WriteSubscriber
观察者模式的优缺点
优点:
- 符合开闭原则,降低了模块之间的耦合,方便根据业务进行扩展
- 可以在运行时进行动态改变观察者集合
缺点:
- 当被观察者持有了大量的观察者,会导致事件的发布变得耗时
注意事项
- 一般采用异步的方式,一方面提高系统响应时间,另一方面防止由于某个观察者出现错误而导致事件发布卡壳,乃至失败
- 防止循环依赖(如果观察者与被观察者之间有循环依赖的话,将会导致互相调用,致使系统崩溃)
具体应用
Spring中的应用
在spring中,事件的订阅与发布使用到了观察者模式
通过ApplicationEvent 、ApplicationListener、ApplicationContext、ApplicationEventMulticaster四个组件实现了项目中最常使用的事件监听器。具体代码可参照源码,再次不做扩展了。