( 十九 )、 设计模式 之 观察者模式(Observer)
( 十九 )、 设计模式 之 观察者模式(Observer)
1、简介
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。JAVA中已经有了对观察者模式的支持类。在 java.util 包里面有一个类 Observable,它实现了大部分我们需要的目标的功能:还有一个接口 Observer,其中定义了 update 的方法,就是观察者的接口。
2、观察者模式的结构说明
- 主题(Subject):主题负责通知已注册的具体的观察者,维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。
- 观察者(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
- 具体观察者(ConcreteObserver):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。
3、实现代码
/**
* @Author
* @ClassName Subject
* @Description 目标对象,存储所有的观察者,并提供注册和删除观察者
* @Date 2023/12/18 20:04
* @Version 1.0
*/
public class Subject {
/**
* 用来保存注册的观察者对象
*/
private final List<Observer> observers = new ArrayList<>();
/**
* 注册观察者对象
*
* @param observer 观察者
*/
public void add(Observer observer) {
observers.add(observer);
}
/**
* 删除观察者对象
*
* @param observer 观察者
*/
public void delete(Observer observer) {
observers.remove(observer);
}
/**
* 通知目标对象
*/
protected void notifyObservers() {
for(Observer observer : observers) {
observer.update();
}
}
}
/**
* @Author
* @ClassName ConcreteObserver
* @Description 具体的目标对象
* @Date 2023/12/18 20:04
* @Version 1.0
*/
public class ConcreteObserver implements Observer {
@Override
public void update() {
System.out.println("目标对象被触发更新");
}
}
/**
* @Author
* @ClassName Observer
* @Description 观察者接口,定义一个更新的接口给那些在目标发生改变的时候被通知的对象
* @Date 2023/12/18 20:04
* @Version 1.0
*/
public interface Observer {
/**
* 更新目标对象
*/
public void update();
}
3、使用场景
一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。比如:发布订阅、事件驱动的系统。
4、观察者模式的优缺点
优点
- 观察者模式支持广播通信,即当被观察者的状态发生变化时,会通知所有的观察者。
- 观察者模式的实现方式符合“开闭原则”,即可以在不改变已存在的实现类的情况下,增加新的观察者类。
缺点
- 如果在被观察者和观察者之间存在循环依赖,那么它们之间会触发循环调用,可能导致系统崩溃。
- 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。