全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-11 6 分钟 ✍️ juanwangdev

Java观察者模式

观察者模式定义对象间一对多依赖,当对象改变时,依赖对象自动收到通知。

模式定义

意图:定义对象间一对多依赖,当一个对象改变时,依赖对象自动更新。

适用场景

  • 事件处理系统
  • 消息订阅
  • 数据绑定
  • GUI事件响应

模式结构

Subject(被观察者)

Java
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;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
        notifyObservers();
    }

    @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);  // 推模型
        }
    }
}

Observer(观察者)

Java
public interface Observer {
    void update(String state);  // 推模型
}

public class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String state) {
        System.out.println(name + "收到通知: " + state);
    }
}

使用示例

Java
ConcreteSubject subject = new ConcreteSubject();

Observer observer1 = new ConcreteObserver("观察者1");
Observer observer2 = new ConcreteObserver("观察者2");

subject.attach(observer1);
subject.attach(observer2);

subject.setState("新状态");
// 观察者1收到通知: 新状态
// 观察者2收到通知: 新状态

推模型 vs 拉模型

模型特点update参数
推模型Subject推送数据传递具体数据
拉模型Observer主动获取传递Subject引用
Java
// 拉模型
public interface Observer {
    void update(Subject subject);
}

public class ConcreteObserver implements Observer {
    @Override
    public void update(Subject subject) {
        String state = ((ConcreteSubject) subject).getState();  // 拉取
        System.out.println("收到通知: " + state);
    }
}

Java内置观察者

Java提供Observable类和Observer接口(已废弃,但仍可用):

Java
public class NewsAgency extends Observable {
    private String news;

    public void setNews(String news) {
        this.news = news;
        setChanged();      // 标记已改变
        notifyObservers(news);  // 通知观察者
    }
}

public class NewsReader implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("收到新闻: " + arg);
    }
}

// 使用
NewsAgency agency = new NewsAgency();
agency.addObserver(new NewsReader());
agency.setNews("重大新闻");

实际应用示例

事件监听

Java
public interface EventListener {
    void onEvent(Event event);
}

public class EventBus {
    private Map<String, List<EventListener>> listeners = new HashMap<>();

    public void subscribe(String eventType, EventListener listener) {
        listeners.computeIfAbsent(eventType, k -> new ArrayList())
                 .add(listener);
    }

    public void publish(String eventType, Event event) {
        List<EventListener> list = listeners.get(eventType);
        if (list != null) {
            for (EventListener listener : list) {
                listener.onEvent(event);
            }
        }
    }
}

Spring事件机制

Java
// 自定义事件
public class CustomEvent extends ApplicationEvent {
    private String message;

    public CustomEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

    public String getMessage() { return message; }
}

// 事件监听器
@Component
public class CustomEventListener {
    @EventListener
    public void handleCustomEvent(CustomEvent event) {
        System.out.println("收到事件: " + event.getMessage());
    }
}

// 发布事件
@Autowired
private ApplicationEventPublisher publisher;

publisher.publishEvent(new CustomEvent(this, "Hello"));

观察者模式优点

  1. Subject与Observer解耦
  2. 支持广播通信
  3. 符合开闭原则

观察者模式缺点

  1. Observer过多影响性能
  2. 无序通知可能导致逻辑问题
  3. 循环依赖导致死循环

注意事项

避免循环调用导致死循环

异步通知注意线程安全

观察者过多可考虑异步处理

Spring事件机制是观察者模式的应用

要点总结

  1. 观察者模式定义一对多依赖,自动通知更新
  2. Subject管理观察者,状态变化时通知
  3. Observer定义更新接口,收到通知执行逻辑
  4. 推模型传递数据,拉模型主动获取
  5. 适用于事件处理、消息订阅、GUI事件

📝 发现内容有误?点击此处直接编辑

← 上一篇 Java装饰器模式
下一篇 → Java解释器模式
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库