Skip to content

观察者模式

字数: 0 字 时长: 0 分钟

简介

观察者模式(Observer Pattern)核心思想是:当一个对象状态发生变化时,自动通知所有依赖它的对象,并自动更新它们。观察者定义了一种一对多的依赖关系,使得一个对象(主题)在状态改变时自动通知所有依赖对象(观察者),以达到以下目的:

  • 发布-订阅机制:状态变化作为事件发布,多个观察者订阅并响应
  • 松耦合:主题和观察者相互独立,易扩展新观察者而不影响主题
  • 动态交互:观察者可以动态注册或注销依赖关系

UML 类图

observer.webp

  • 主题(Subject):主题对象,定义了观察者注册、移除和通知的接口,同时维护观察者列表
  • 具体主题(ConcreteSubject):是实现主题接口,在自己状态改变时,通知所有观察者
  • 观察者(Observer):定义了观察者响应主题通知的更新接口
  • 具体观察者(ConcreteObserver):实现观察者接口,接受到通知后,做出具体响应

实现示例

展示股票价格变动时通知多个观察者(如警报系统和日志系统)

java
// 1. 观察者接口
interface StockObserver {
    void update(double price);
}

// 2. 主题接口
interface StockSubject {
    void registerObserver(StockObserver observer);
    void removeObserver(StockObserver observer);
    void notifyObservers();
}

// 3. 具体观察者 (警报系统、日志系统)
class AlertObserver implements StockObserver {
    @Override
    public void update(double price) {
        if (price > 150.0) {
            System.out.println("股票价格太高!");
        }
    }
}
class LogObserver implements StockObserver {
    @Override
    public void update(double price) {
        System.out.println("记录当前价格变动为: " + price);
    }
}

// 4. 具体主题 (股票价格)
class StockPrice implements StockSubject { 
    private double currentPrice = 100.0;
    private List<StockObserver> observers = new ArrayList<>();
    public void changePrice(double newPrice) {
        if (currentPrice != newPrice) {
            currentPrice = newPrice;
            notifyObservers();
        }
    }
    @Override
    public void registerObserver(StockObserver observer) {
        observers.add(observer);
    }
    @Override
    public void removeObserver(StockObserver observer) {
        observers.remove(observer);
    }
    @Override
    public void notifyObservers() {
        for (StockObserver observer : observers) {
            observer.update(currentPrice);
        }
    }
}

// 5. 调用示例
public static void main(String[] args) {
    StockPrice stockPrice = new StockPrice();
    StockObserver alertObserver = new AlertObserver();
    StockObserver logObserver = new LogObserver();
    stockPrice.registerObserver(alertObserver);
    stockPrice.registerObserver(logObserver);
    // 改变价格触发通知
    stockPrice.changePrice(160.0);
}