Observer Design Pattern - tenji/ks GitHub Wiki

观察者模式

在软件设计和工程中,观察者模式(Observer Pattern)是一种软件设计模式,其中称为主题的对象维护其依赖项(称为观察者)的列表,并通常通过调用它们的某个方法自动通知它们任何状态更改。观察者模式通常用于在事件驱动(event-driven)软件中实现分布式事件处理(event-handling)系统。

一、结构

1.1 类图(静态结构)

observer-class-structure

1.2 时序图(动态结构)

observer-pattern-seq-structure

二、代码示例

observer-demo-structure

Subject 类(Publisher Interface)

public interface Subject {
    void addObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

Observer 类(Subscriber Interface)

public interface Observer {
    void update(String weather);
}

WeatherStation 类(ConcreteSubject)

public class WeatherStation implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String weather;

    @Override
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(weather);
        }
    }

    public void setWeather(String newWeather) {
        this.weather = newWeather;
        notifyObservers();
    }
}

PhoneDisplay 类(ConcreteObserver1)

public class PhoneDisplay implements Observer {
    private String weather;

    @Override
    public void update(String weather) {
        this.weather = weather;
        display();
    }

    private void display() {
        System.out.println("Phone Display: Weather updated - " + weather);
    }
}

TVDisplay 类(ConcreteObserver2)

class TVDisplay implements Observer {
    private String weather;

    @Override
    public void update(String weather) {
        this.weather = weather;
        display();
    }

    private void display() {
        System.out.println("TV Display: Weather updated - " + weather);
    }
}

Driver Program

public class WeatherApp {
    public static void main(String[] args) {
        WeatherStation weatherStation = new WeatherStation();

        Observer phoneDisplay = new PhoneDisplay();
        Observer tvDisplay = new TVDisplay();

        weatherStation.addObserver(phoneDisplay);
        weatherStation.addObserver(tvDisplay);

        // Simulating weather change
        weatherStation.setWeather("Sunny");

        // Output:
        // Phone Display: Weather updated - Sunny
        // TV Display: Weather updated - Sunny
    }
}

三、优点

  • 符合开/闭原则。你可以引入新的订阅者类,而无需更改发布者的代码(如果有发布者接口,则反之亦然);
  • 可以在运行时建立对象之间的关系;
  • 适合事件处理。观察者模式经常用于事件处理系统,当系统中发生事件时,观察者(监听者)可以对这些事件做出反应,而不需要事件源明确了解观察者。

四、缺点

  • 订阅者会以随机顺序收到通知。

五、观察者模式 vs 反应器模式(Reactor Pattern)

观察者模式与 Reactor 模式非常相似,个人认为,Reactor 模式算是观察者模式的扩展。Reactor 模式下,Handle 可以认为是生产者,Event Handler 可以认为是观察者,观察者模式和 Reactor 模式重要的区别在于,Reactor 模式使用中央请求处理程序(Central Request Handler),也就是 Reactor 来将生产者的消息通知给观察者,而观察者模式则让消费者直接与生产者对话。

从 Reactor 样例代码以及结构图可以看出来,如果将 Reactor 作为生产者,Event Handler 作为观察者,那就是一个标准的观察者模式。

更多关于反应器模式,传送门

∞、参考链接

⚠️ **GitHub.com Fallback** ⚠️