> For the complete documentation index, see [llms.txt](https://yunzhao.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yunzhao.gitbook.io/notes/computer-science/design-patterns/behavioral/observer.md).

# Observer

## 介绍

定义：观察者模式定义了对象之间的一对多依赖，当一个对象的状态改变时，它的所有依赖者都会收到通知并更新。Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

在具体实现时需要注意：

* 若是循环同步通知，需要注意观察者的执行时间，若执行太久，则会阻塞后面观察者。可以使用异步、超时等方法解决。
* 需要注意重复注册观察者问题。

又叫监听器模式、发布/订阅模式。

## 类图

![](/files/-Lflx1q4mbpXkYouWnAw)

## 源码

### Java 内置的观察者模式

![](/files/-LflzZR-Dm72prAG2Ly8)

注意要先调用 setChanged 方法。

缺点：Observable 是一个类而不是接口，而且本身也没有实现接口。

### Guava EventBus

```java
package com.google.common.eventbus;

public class EventBus {
  private final SubscriberRegistry subscribers = new SubscriberRegistry(this);

  public void register(Object object) {
    subscribers.register(object);
  }
  
  public void unregister(Object object) {
    subscribers.unregister(object);
  }

  public void post(Object event) {
    Iterator<Subscriber> eventSubscribers = subscribers.getSubscribers(event);
    if (eventSubscribers.hasNext()) {
      dispatcher.dispatch(event, eventSubscribers);
    } else if (!(event instanceof DeadEvent)) {
      // the event had no subscribers and was not itself a DeadEvent
      post(new DeadEvent(this, event));
    }
  }
}

final class SubscriberRegistry {
  private final ConcurrentMap<Class<?>, CopyOnWriteArraySet<Subscriber>> subscribers =
      Maps.newConcurrentMap();
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yunzhao.gitbook.io/notes/computer-science/design-patterns/behavioral/observer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
