简介
观察者模式(Observer Pattern)
是一种行为设计模式,它定义了一种一对多的依赖关系,使得多个观察者对象
同时监听某一个主题对象
。当主题对象状态发生改变时,它会通知所有观察者对象
,使得它们可以自动更新自己。
在观察者模式
中,主题对象负责维护观察者列表
,同时提供注册
和删除观察者
的接口,以及通知观察者
的接口。观察者对象
负责将自己注册到主题对象中,并实现观察者接口,以便在主题对象状态发生改变时能够接收通知,并进行相应的更新操作。
观察者模式
可以用于解耦观察者
和主题对象之间的关系,使得它们可以独立变化,而不会相互影响。这种模式常用于事件驱动系统中,如GUI程序、消息传递系统等。
简单实现案例
import java.util.ArrayList;
import java.util.List;
// 主题对象
public class Clock {
private final List<Observer> observers = new ArrayList<>();
// 注册观察者
public void attach(Observer observer) {
observers.add(observer);
}
// 删除观察者
public void detach(Observer observer) {
observers.remove(observer);
}
// 通知所有观察者
public void notifyObservers(String time) {
for (Observer observer : observers) {
observer.update(time);
}
}
// 模拟计时器,每秒钟触发一次事件
public void run() throws InterruptedException {
while (true) {
Thread.sleep(1000);
String time = getTime();
notifyObservers(time);
}
}
// 获取当前时间
private String getTime() {
return System.currentTimeMillis() / 1000L + "";
}
}
// 观察者接口
interface Observer {
void update(String time);
}
// 观察者对象A
class ObserverA implements Observer {
@Override
public void update(String time) {
System.out.println("ObserverA收到通知,当前时间为:" + time);
}
}
// 观察者对象B
class ObserverB implements Observer {
@Override
public void update(String time) {
System.out.println("ObserverB收到通知,当前时间为:" + time);
}
}
// 测试代码
class Test {
public static void main(String[] args) throws InterruptedException {
Clock clock = new Clock();
ObserverA observerA = new ObserverA();
ObserverB observerB = new ObserverB();
clock.attach(observerA); // 注册观察者A
clock.attach(observerB); // 注册观察者B
clock.run(); // 启动计时器,每秒钟通知观察者
}
}
在主题中我们需要设置分别设置一个添加,注册,删除观察者的方法,也就是在Clock
中,然后我们创建了观察者接口
实现了具体的观察者,通过这个简单的例子我们可以发现当我们的时钟也就是我们的主题,我们的参考对象发生改变时,我们可以使用观察者模式
立刻做出相应的处理。
模式详解
当我们使用观察者设计模式时我们必须包含如下角色
- 观察对象
也就是我们的主题,主题角色其中定义了注册,删除,以及通知观察者的方法。 - 具体的观察对象
也就是我们具体的被观察对象,当其发生变化时,他会通知我们的观察者,在我们的案例中由Clock
担任。 - 观察者
观察者角色负责接收来自subject
角色的状态变化的通知,为此他会声明update
方法,在示例程序中由我们的Observer
担任。 - 具体的观察者
当更新的方法被调用后,会过去要观察的对象的最新状态,在示例程序中由我们的ObserverA
和ObserverB
担任。
模式类图
优缺点
观察者模式的优点
- 解耦性:观察者模式将观察者和主题对象解耦,使它们可以独立变化,而不会相互影响。
- 可扩展性:在观察者模式中,可以很容易地添加或删除观察者,而不会影响主题对象或其他观察者的操作。
- 通用性:观察者模式可以用于多种场景,如事件处理、消息传递等。
观察者模式的缺点
- 运行效率:当主题对象的状态发生改变时,会通知所有观察者对象,这可能会导致性能问题,特别是在观察者数量较多时。
- 数据一致性:当主题对象状态发生改变时,可能会影响观察者之间的数据一致性,特别是当观察者之间存在依赖关系时。
- 设计复杂性:在观察者模式中,可能需要设计多个观察者和主题对象,这会增加系统的复杂性,特别是当需要处理多个主题对象时。