# 观察者模式

## 目录
- [观察者模式概念](#观察者模式概念)
- [观察者模式实现](#观察者模式实现)
- [观察者模式应用](#观察者模式应用)
- [观察者模式优缺点](#观察者模式优缺点)
- [观察者模式最佳实践](#观察者模式最佳实践)
- [面试常见问题](#面试常见问题)

---

## 观察者模式概念

### 定义

```java
// 观察者模式：定义对象间一对多的依赖关系
// 当一个对象状态改变时，所有依赖它的对象都会收到通知
// 并自动更新
```

### 角色

```java
// 1. Subject（主题）：被观察的对象
// 2. Observer（观察者）：观察主题的对象
// 3. ConcreteSubject（具体主题）
// 4. ConcreteObserver（具体观察者）
```

---

## 观察者模式实现

### 基本实现

```java
// 观察者接口
public interface Observer {
    void update(String message);
}

// 主题接口
public interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers();
}

// 具体主题
public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;
    
    @Override
    public void attach(Observer observer) {
        observers.add(observer);
    }
    
    @Override
    public void detach(Observer observer) {
        observers.remove(observer);
    }
    
    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(state);
        }
    }
    
    public void setState(String state) {
        this.state = state;
        notifyObservers();
    }
}

// 具体观察者
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);
    }
}

// 使用
Subject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("Observer1");
Observer observer2 = new ConcreteObserver("Observer2");

subject.attach(observer1);
subject.attach(observer2);
subject.setState("New State");
```

---

## 观察者模式应用

### Android 中的应用

#### 1. LiveData

```java
// LiveData 使用观察者模式
LiveData<String> liveData = new MutableLiveData<>();
liveData.observe(this, new Observer<String>() {
    @Override
    public void onChanged(String s) {
        // 数据变化时自动更新
    }
});
```

#### 2. EventBus

```java
// EventBus 使用观察者模式
// 注册
EventBus.getDefault().register(this);

// 订阅
@Subscribe
public void onEvent(MessageEvent event) {
    // 处理事件
}

// 发布
EventBus.getDefault().post(new MessageEvent());
```

#### 3. BroadcastReceiver

```java
// BroadcastReceiver 使用观察者模式
BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 接收广播
    }
};

registerReceiver(receiver, new IntentFilter("ACTION"));
```

---

## 观察者模式优缺点

### 优点

```java
// 1. 解耦：主题和观察者松耦合
// 2. 扩展：易于添加新的观察者
// 3. 通知：自动通知所有观察者
// 4. 符合开闭原则
```

### 缺点

```java
// 1. 如果观察者很多，通知开销大
// 2. 如果观察者之间有循环依赖，可能导致系统崩溃
// 3. 观察者不知道其他观察者的存在
```

---

## 观察者模式最佳实践

### 1. 避免内存泄漏

```java
// 及时取消注册
@Override
protected void onDestroy() {
    super.onDestroy();
    EventBus.getDefault().unregister(this);
    liveData.removeObserver(observer);
}
```

### 2. 使用弱引用

```java
// 使用弱引用避免内存泄漏
private WeakReference<Observer> observerRef;
```

### 3. 异步通知

```java
// 如果观察者处理耗时，使用异步通知
// 避免阻塞主题
```

---

## 面试常见问题

### Q1: 观察者模式的原理？

**答案：**
- 定义对象间一对多的依赖关系
- 主题状态改变时，自动通知所有观察者
- 观察者收到通知后自动更新

### Q2: Android 中的观察者模式应用？

**答案：**
1. **LiveData**：数据变化通知
2. **EventBus**：事件总线
3. **BroadcastReceiver**：广播接收器

### Q3: 观察者模式的优缺点？

**答案：**
- **优点**：解耦、易于扩展、自动通知
- **缺点**：通知开销大、可能循环依赖

### Q4: 如何避免观察者模式的内存泄漏？

**答案：**
1. 及时取消注册
2. 使用弱引用
3. 使用生命周期感知组件（LiveData）

---

*最后更新：2024年*
