观察者模式

观察者模式允许对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。在这种模式中,发生状态改变的对象被称为主题(Subject),依赖它的对象被称为观察者(Observer)

优点:

  1. 观察者和主题之间的解耦:主题只需要知道观察者实现了Observer接口,而无需了解具体的实现细节。
  2. 可以动态添加和删除观察者:通过调用registerObserver和removeObserver方法,可以在运行时添加和删除观察者。
  3. 主题和观察者之间的通信是自动的:当主题的状态发生变化时,观察者会自动得到通知并更新自己的状态

源码使用

java.util.Observable类实现了主题(Subject)的功能,而java.util.Observer接口则定义了观察者(Observer)的方法。

通过调用Observable对象的notifyObservers()方法,可以通知所有注册的Observer对象,让它们更新自己的状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 银行账户类
public class BankAccount extends Observable {
private double balance;
// 构造函数
public BankAccount(double balance) {
this.balance = balance;
}
// 存款操作
public void deposit(double amount) {
balance += amount;
setChanged(); // 表示状态已经改变
notifyObservers(); // 通知所有观察者
}
// 取款操作
public void withdraw(double amount) {
balance -= amount;
setChanged(); // 表示状态已经改变
notifyObservers(); // 通知所有观察者
}
// 获取当前余额
public double getBalance() {
return balance;
}
// 主函数
public static void main(String[] args) {
BankAccount account = new BankAccount(1000.0);
// 创建观察者
Observer observer1 = new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println("客户1: 余额已更新为 " +
((BankAccount)o).getBalance());
}
};
Observer observer2 = new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println("客户2: 余额已更新为 " +
((BankAccount)o).getBalance());
}
};
// 注册观察者
account.addObserver(observer1);
account.addObserver(observer2);
// 存款操作,触发观察者更新
account.deposit(100.0);
// 取款操作,触发观察者更新
account.withdraw(50.0);
}
}

这个案例中,BankAccount类继承了java.util.Observable类,表示它是一个主题(Subject)。在存款或取款操作时,它会调用setChanged()方法表示状态已经改变,并调用notifyObservers()方法通知所有观察者(Observer)。

在主函数中,我们创建了两个观察者(observer1和observer2),它们分别实现了Observer接口的update()方法。当观察者收到更新通知时,它们会执行自己的业务逻辑,比如更新显示信息。

观察者模式和发布订阅模式的区别

  1. 通信方式:观察者模式中,观察者与被观察者之间存在直接的关联关系,而发布-订阅模式中,发布者和订阅者通过一个第三方组件(消息代理或事件总线)进行通信,彼此之间不存在直接关联关系。
  2. 系统复杂性:发布-订阅模式引入了一个额外的组件(消息代理或事件总线),增加了系统的复杂性,但同时也提高了系统的灵活性和可扩展性。
  3. 使用场景:观察者模式适用于需要将状态变化通知给其他对象的情况,而发布-订阅模式适用于事件驱动的系统,尤其是那些需要跨越多个模块或组件进行通信的场景

发布订阅模式的优点

  1. 通信方式:观察者模式中,观察者与被观察者之间存在直接的关联关系,而发布-订阅模式中,发布者和订阅者通过一个第三方组件(消息代理或事件总线)进行通信,彼此之间不存在直接关联关系。
  2. 系统复杂性:发布-订阅模式引入了一个额外的组件(消息代理或事件总线),增加了系统的复杂性,但同时也提高了系统的灵活性和可扩展性。
  3. 使用场景:观察者模式适用于需要将状态变化通知给其他对象的情况,而发布-订阅模式适用于事件驱动的系统,尤其是那些需要跨越多个模块或组件进行通信的场景