观察者模式

点击阅读:设计模式系列文章


1. 观察者模式的定义

观察者模式 (Observer Pattern)是一种行为设计模式 ,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

观察者模式所做的工作就是在解除耦合。使耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。

观察者模式解决了以下关键问题:

  • 状态同步难题:当多个对象需要同步状态时,避免硬编码的依赖关系
  • 动态订阅机制:运行时动态添加/移除观察者的能力
  • 事件驱动架构:构建响应式系统的基石

2. 观察者模式的结构

  1. Subject:抽象主题,一般为抽象类或接口,将所有的观察者引用存在一个集合里,并提供了增加和删除观察者对象的接口。
java 复制代码
public abstract class Subject {
    private List<Observer> observers = new ArrayList<>();
    

    private String state;
    
    public void setState(String state) {
        this.state = state;
        notifyObservers(); // 状态变更时通知观察者
    }
    
    public String getSubjectState(){
        return subjectState;
    }
    
    //添加观察者
    public void attach(Observer observer) {
        observers.add(observer);
    }

    //删除观察者
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    //通知所有观察者
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}
  1. ConcreteSubject:具体主题,将有关联状态存入具体观察者对象。在具体主题的内部状态改变时,给所有登记过的观察者发出通知。
java 复制代码
public class ConcreteSubject extends Subject {

}
  1. Observer:抽象观察者,一般为抽象类或接口,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。
java 复制代码
public interface Observer {
    void update();
}
  1. ConcreteObserver:具体观察者,实现具体观察者所要求的更新接口,以便使本身的状态与主题的状态相协调。
java 复制代码
public class ConcreteObserver implements Observer {
    private String name;
    private String subjectState;
    private Subject subject;

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

    @Override
    public void update() {
        subjectState = subject.getSubjectState();
        System.out.println("ConcreteObserver", "Observer " + name + ", state " + subjectState);
    }
}
  1. 客户端代码
java 复制代码
Subject subject = new ConcreteSubject();
subject.attach(new ConcreteObserver("Zhang San", subject));
subject.attach(new ConcreteObserver("Li Si", subject));
subject.attach(new ConcreteObserver("Wang Wu", subject));
subject.setSubjectState("Change");

3. 观察者模式 Java 内置接口的实现

Java 已经为观察者模式准备好了相关的接口和抽象类了。

java 复制代码
// 继承Observable类
class WeatherStation extends Observable {
    private float temperature;
    
    public void setTemperature(float temp) {
        this.temperature = temp;
        setChanged(); // 标记状态已改变
        notifyObservers(); // 通知观察者
    }
}

// 实现Observer接口
class PhoneDisplay implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof WeatherStation) {
            System.out.println("");
        }
    }
}

// 使用示例
WeatherStation station = new WeatherStation();
station.addObserver(new PhoneDisplay());
station.setTemperature(25.5f);

4. 观察者模式的优缺点

优点 :

  • 解耦设计:主题和观察者之间保持最小依赖
  • 动态扩展:无需修改主题即可增加新观察者
  • 事件驱动:支持分布式事件处理系统
  • 重用性高:主题和观察者可以独立复用

缺点 :

  • 通知顺序不可控:观察者接收通知的顺序不确定
  • 性能问题:大量观察者可能导致通知过程耗时
  • 循环依赖风险:不当实现可能导致循环调用

5. 观察者模式的相关实践

5.1 推拉模型

  • 推模型:主题主动将详细数据发送给观察者
  • 拉模型:观察者收到通知后主动从主题获取数据
java 复制代码
// 推模型实现
protected void notifyObservers(Object data) {
    for (Observer o : observers) {
        o.update(data); // 直接传递数据
    }
}

// 拉模型实现(推荐)
protected void notifyObservers() {
    for (Observer o : observers) {
        o.update(this); // 传递主题引用
    }
}

5.2 异步通知机制

线程安全优化,避免阻塞主题线程:

java 复制代码
public class ConcurrentSubject {
    private final CopyOnWriteArrayList<Observer> observers = 
        new CopyOnWriteArrayList<>();
    
    public void notifyObservers() {
        for (Observer o : observers) {
            // 使用线程池异步处理
            executorService.submit(() -> o.update(this));
        }
    }
}
相关推荐
用户0925 分钟前
MVI架构如何改变Android开发模式
android·面试·kotlin
BeyondCode程序员31 分钟前
设计原则讲解与业务实践
设计模式·架构
青草地溪水旁1 小时前
设计模式(C++)详解——迭代器模式(1)
c++·设计模式·迭代器模式
青草地溪水旁1 小时前
设计模式(C++)详解——迭代器模式(2)
java·c++·设计模式·迭代器模式
9号达人1 小时前
Java18 新特性详解与实践
java·后端·面试
苍老流年1 小时前
1. 设计模式--工厂方法模式
设计模式·工厂方法模式
学历真的很重要1 小时前
Claude Code 万字斜杠命令指南
后端·语言模型·面试·职场和发展·golang·ai编程
PaoloBanchero2 小时前
Unity 虚拟仿真实验中设计模式的使用 ——策略模式(Strategy Pattern)
unity·设计模式·策略模式
PaoloBanchero2 小时前
Unity 虚拟仿真实验中设计模式的使用 —— 观察者模式(Observer Pattern)
观察者模式·unity·设计模式
Mr_WangAndy2 小时前
C++设计模式_创建型模式_单件模式
c++·单例模式·设计模式