一、什么是观察者模式
概念:
- 观察者模式(Observer Pattern)是一种
行为型设计模式
,它定义了一种一对多的依赖关系, 一是指主题对象,多是指观察者对象,观察者对象监听主题对象的状态变化。当主题对象改变时,对应的观察者对象就会收到通知并更新自身。
角色组成:
-
Subject(主题):即被观察者,它是一个抽象类或接口,定义了注册和撤销观察者对象的方法,以及通知观察者的方法。
-
ConcreteSubject(具体主题):实现了主题接口,它具有添加、删除和通知观察者的功能,当其内部状态发生改变时,会通知所有注册的观察者。
-
Observer(观察者):也称为订阅者或监听者,它是一个抽象类或接口,定义了观察者接收通知并更新自身的方法。
-
ConcreteObserver(具体观察者):实现了观察者接口,收到主题的通知即会执行相应操作,以便与主题保持一致。
二、观察者模式的优点
-
解耦:主题和观察者独立封装,主题对象不需要知道观察者的具体实现,只需要通过观察者接口进行通信。
-
可扩展性:一个观察者对象的增删改不会影响其他对象通信,主题对象也不用修改代码,符合开闭原则。
-
通知机制:主题对象的状态发生改变时,会自动通知所有注册的观察者对象,即实现了对象间的动态通信。
-
易于维护:观察者模式的结构清晰,代码可读性好,每个角色的功能单一,易于理解和维护。
-
代码复用:由于观察者模式解耦了主题和观察者对象,使得它们可以被独立地复用,不需要修改原有的代码。
总之,观察者模式是一种灵活、可扩展且可维护的设计模式,适用于一对多的通信场景,常见于事件驱动的系统设计、图形界面框架、消息队列等场景中。
三、观察者模式的应用场景
-
需要通知时:当一个对象的状态改变需要通知其他对象,并且不知道通知的对象是谁时,可以使用观察者模式。例如,一个主题对象(被观察者)的状态变化需要通知多个观察者对象,比如
电商平台上商品价格变化通知用户
。 -
需要解耦时:一个对象需要将自己的状态变化通知给其他对象,并且不关心其他对象的具体实现时,可以使用观察者模式。例如,
一个发布者将消息发布给多个订阅者,而发布者不需要关心每个订阅者的处理方式
。 -
一对多依赖时:一个对象的改变会影响其他多个对象时,可以使用观察者模式。例如,
一支股票的价格变化会影响到所有交易者的决策
。
示例:新闻订阅系统
假设有一个新闻发布者(被观察者)和多个新闻订阅者(观察者)。当新闻发布者发布一条新闻时,所有订阅者都会收到通知并更新自己的新闻列表。这个问题可以使用观察者模式来解决。
在该示例中,新闻发布者是主题对象,新闻订阅者是观察者对象。新闻发布者可以注册和删除订阅者,并且在发布新闻时会通知所有订阅者。订阅者可以更新自己的新闻列表。
通过使用观察者模式,新闻发布者和订阅者对象之间解耦,实现了一对多的通信机制,同时也方便了新闻发布者的扩展和维护。
四、观察者模式的Java实现
在Java中,可以通过以下步骤来实现观察者模式:
- 定义观察者接口(Observer):观察者接口中声明了更新方法,用于在被观察者状态变化时进行通知。
java
public interface Observer {
void update();
}
- 定义被观察者接口(Subject):被观察者接口中声明了添加、删除和通知观察者的方法。
java
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
- 实现观察者类(具体观察者):具体观察者类实现了观察者接口,并实现了更新方法。
java
public class ConcreteObserver implements Observer {
@Override
public void update() {
// 执行更新操作
}
}
- 实现被观察者类(具体被观察者):具体被观察者类实现了被观察者接口,并维护了观察者列表,实现了添加、删除和通知观察者的方法。
java
public class ConcreteSubject 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() {
for (Observer observer : observers) {
observer.update();
}
}
}
- 使用观察者模式:在实际应用中,可以创建具体观察者和具体被观察者对象,然后将观察者注册到被观察者中,并在需要的时候调用被观察者的通知方法。
java
public class Main {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observer1 = new ConcreteObserver();
ConcreteObserver observer2 = new ConcreteObserver();
subject.registerObserver(observer1);
subject.registerObserver(observer2);
// 状态变化后通知观察者
subject.notifyObservers();
}
}
以上,我们就完成了观察者模式的Java示例。在具体的应用场景中,可以根据需要扩展、修改和定制观察者模式的实现。
五、SpringBoot中观察者模式的实现
在Spring Boot中,可以使用Spring框架中的事件机制来实现观察者模式。Spring的事件机制基于观察者模式,通过发布-订阅模型实现。
实现Spring Boot中观察者模式的步骤如下:
- 定义事件类:创建一个继承自ApplicationEvent的自定义事件类。
java
public class CustomEvent extends ApplicationEvent {
public CustomEvent(Object source) {
super(source);
}
// 可以定义一些自定义的属性和方法
}
- 定义观察者类:创建一个实现ApplicationListener接口的观察者类。
java
@Component
public class CustomEventListener implements ApplicationListener<CustomEvent> {
@Override
public void onApplicationEvent(CustomEvent event) {
// 在事件发生时,执行相应的逻辑
}
}
- 发布事件:在需要的地方通过ApplicationContext来发布自定义事件。
java
@Autowired
private ApplicationContext applicationContext;
public void publishEvent() {
CustomEvent event = new CustomEvent(this);
applicationContext.publishEvent(event);
}
通过上述步骤,我们就可以在Spring Boot中实现观察者模式。当发布自定义事件时,所有订阅该事件的观察者都会收到通知并执行相应的逻辑。可以根据需要在观察者类中进行逻辑处理,例如发送通知、更新数据等操作。
需要注意的是,在使用Spring的事件机制时,观察者类需要被Spring容器管理,可以通过@Component注解或者其他方式将观察者类注入到容器中。另外,发布事件的类需要通过@Autowired或者其他方式获取ApplicationContext来发布事件。