观察者模式详解
观察者模式是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,当主题对象发生变化时,它的所有依赖者(观察者)都会收到通知并自动更新。这种模式又被称为发布-订阅模式。
1. 模式结构
观察者模式包含以下主要角色:
-
Subject(主题): 定义一个抽象接口,维护一个用于存放观察者对象的集合,提供对观察者的增加、删除和通知的操作。
-
ConcreteSubject(具体主题): 具体主题是主题的具体实现类,负责维护观察者列表并发送通知。
-
Observer(观察者): 定义一个抽象接口,用于接收主题的通知。
-
ConcreteObserver(具体观察者): 具体观察者是观察者的具体实现类,实现接收通知并更新的具体逻辑。
2. 优缺点比较
优点 | 缺点 |
---|---|
松耦合:主题和观察者之间松散耦合,主题只知道观察者的接口而不知道具体实现。 | 观察者过多时,通知所有观察者可能会导致性能问题。 |
支持广播通信 | 如果一个观察者的更新操作耗时较长,可能会影响整体性能。 |
可扩展性 | |
遵循开闭原则 |
3. 使用场景
观察者模式通常在以下情况下使用:
- 一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要改变。
- 一个对象必须通知其他对象,而且你不希望这些对象是紧密耦合的。
- 系统的数据分离层,将数据更新操作和具体的业务逻辑分开。
4. 示例代码
java
// 1. Subject 主题
public interface Subject {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers(String message);
}
// 2. ConcreteSubject 具体主题
import java.util.ArrayList;
import java.util.List;
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
// 3. Observer 观察者
public interface Observer {
void update(String message);
}
// 4. ConcreteObserver 具体观察者
public class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received message: " + message);
}
}
// 5. Client 客户端
public class Client {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("Observer 1");
Observer observer2 = new ConcreteObserver("Observer 2");
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers("Hello, observers!");
}
}
以上示例中,ConcreteSubject
是具体主题类,实现了 Subject
接口。ConcreteObserver
是具体观察者类,实现了 Observer
接口。客户端通过 ConcreteSubject
注册观察者,当主题发生变化时,所有注册的观察者都会收到通知。