什么是观察者模式?
观察者模式(Observer Pattern)是一种行为型设计模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
观察者模式包含以下几个关键角色:
-
主题(Subject):也称为被观察者或发布者,它维护一组观察者对象,并在状态变化时通知观察者。
-
观察者(Observer):也称为订阅者或观察者,它定义了接收通知并进行相应操作的方法。
观察者模式优点:
- 一个观察目标可以对应多个观察者,而这些观察者之间没有相互联系,所以能够根据需要增加和删除观察者,使得系统更易于扩展,符合开闭原则;
- 并且观察者模式让目标对象和观察者松耦合,虽然彼此不清楚对方的细节,但依然可以交互,目标对象只知道一个具体的观察者列表,但并不认识任何一个具体的观察者,它只知道他们都有一个共同的接口。
观察者模式缺点:
- 如果存在很多个被观察者的话,那么将需要花费一定时间通知所有的观察者,如果观察者与被观察者之间存在循环依赖的话,那么可能导致系统崩溃,
- 观察者模式没有相应的机制让观察者知道被观察对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
代码实例
// 主题接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 观察者接口
interface Observer {
void update(String message);
}
// 具体主题
class ConcreteSubject implements Subject {
private List<Observer> observers;
private String message;
ConcreteSubject() {
this.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(message);
}
}
void setMessage(String message) {
this.message = message;
notifyObservers();
}
}
// 具体观察者
class ConcreteObserver implements Observer {
@Override
public void update(String message) {
System.out.println("Received message: " + message);
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver();
subject.registerObserver(observer1);
Observer observer2 = new ConcreteObserver();
subject.registerObserver(observer2);
subject.setMessage("Hello, observers!");
}
}
从上述代码中我们可以看到,主题接口 Subject
定义了注册观察者、移除观察者和通知观察者的方法。具体主题 ConcreteSubject
实现了主题接口,并在状态变化时通知观察者。
观察者接口 Observer
定义了接收通知并进行相应操作的方法。具体观察者 ConcreteObserver
实现了观察者接口,并在收到通知时输出接收到的消息。
在客户端代码中,首先创建一个主题实例 subject
,然后创建两个观察者实例 observer1
和 observer2
。通过调用 subject.registerObserver(observer)
方法将观察者注册到主题中。当调用 subject.setMessage(message)
时,主题的状态变化会通知所有观察者。
观察者模式可以实现对象之间的松耦合,使得系统的各个部分可以独立地进行扩展和复用。它常被应用于事件驱动系统、GUI框架以及需要在对象之间建立一对多关系的场景。