设计模式:观察者模式

观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式通常被用来实现事件处理系统、实时数据更新、状态监控等多种场景。

关键组件:

  1. Subject(主题/被观察者):它是被观察的对象,负责维护一个观察者列表,并在状态发生改变时通知所有的观察者。Subject通常会提供注册(attach)、注销(detach)观察者以及通知(notify)观察者的方法。

  2. Observer(观察者) :它是观察主题状态变化的对象,提供一个更新自己的方法(通常称为update)。当Subject状态变化时,它会调用所有已注册的Observer的update方法。

工作流程:

  1. 注册过程:观察者向主题注册自己,表明自己对主题状态变化感兴趣。
  2. 状态改变:当主题状态发生改变时,它会自动通知所有已注册的观察者。
  3. 更新操作:每个观察者接收到通知后,根据收到的信息执行相应的操作来更新自己的状态。

优点:

  • 松耦合:主题和观察者之间仅通过接口关联,降低了模块间的耦合度,使得两者可以独立地变化。
  • 扩展性:可以轻松地增加新的观察者,而无需修改主题或其他现有的观察者代码。
  • 灵活性:能够支持广播通信,即一个主题状态的改变可以通知多个观察者。

实现示例(Java):

以下是使用Java实现观察者模式的一个简单示例。在这个例子中,我们将模拟一个天气预报系统,其中WeatherData充当被观察者(Subject),负责收集气象数据并通知观察者(Observer)------在这里是具体的显示设备,如CurrentConditionsDisplay

1. 创建观察者接口

首先,定义一个观察者接口,声明更新方法。

java 复制代码
import java.util.EventObject;

// 观察者接口
interface Observer {
    void update(EventObject event);
}

2. 定义被观察者接口与具体被观察者

接下来,定义被观察者接口,包含注册、删除观察者以及通知观察者的方法。同时,实现具体的被观察者类WeatherData

java 复制代码
import java.util.ArrayList;
import java.util.List;

// 被观察者接口
interface Observable {
    void addObserver(Observer o);
    void deleteObserver(Observer o);
    void notifyObservers();
}

// 具体被观察者 - 天气数据
class WeatherData implements Observable {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData() {
        this.observers = new ArrayList<>();
    }

    public void measurementsChanged() {
        notifyObservers();
    }

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

    @Override
    public void deleteObserver(Observer o) {
        observers.remove(o);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(new WeatherEvent(this, temperature, humidity, pressure));
        }
    }

    // 其他方法略,如setMeasurements等用于更新数据
}

3. 创建事件对象

定义一个事件对象,用于传递给观察者。

java 复制代码
// 事件对象
class WeatherEvent extends EventObject {
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherEvent(Object source, float temperature, float humidity, float pressure) {
        super(source);
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
    }

    public float getTemperature() {
        return temperature;
    }

    public float getHumidity() {
        return humidity;
    }

    public float getPressure() {
        return pressure;
    }
}

4. 实现具体观察者

定义具体的观察者类,比如显示当前天气状况的显示器。

java 复制代码
// 具体观察者 - 显示当前天气状况
class CurrentConditionsDisplay implements Observer {
    private float temperature;
    private float humidity;

    @Override
    public void update(EventObject event) {
        if (event instanceof WeatherEvent) {
            WeatherEvent weatherEvent = (WeatherEvent) event;
            this.temperature = weatherEvent.getTemperature();
            this.humidity = weatherEvent.getHumidity();
            display();
        }
    }

    public void display() {
        System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
    }
}

5. 客户端代码

最后,客户端代码创建被观察者和观察者实例,并模拟数据更新过程。

java 复制代码
public class ObserverPatternDemo {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();

        weatherData.addObserver(currentDisplay);

        // 模拟气象数据变化
        weatherData.setMeasurements(80, 65, 30.4f); // 假设这是更新数据的方法
    }
}

请注意,为了简洁起见,示例中省略了某些方法的实现细节,如setMeasurements方法,实际应用中应确保在数据更新时调用measurementsChanged方法来通知观察者。

相关推荐
刷帅耍帅3 小时前
设计模式-享元模式
设计模式·享元模式
刷帅耍帅3 小时前
设计模式-模版方法模式
设计模式
刷帅耍帅5 小时前
设计模式-桥接模式
设计模式·桥接模式
MinBadGuy6 小时前
【GeekBand】C++设计模式笔记5_Observer_观察者模式
c++·设计模式
刷帅耍帅6 小时前
设计模式-生成器模式/建造者模式Builder
设计模式·建造者模式
蜡笔小新..1 天前
【设计模式】软件设计原则——开闭原则&里氏替换&单一职责
java·设计模式·开闭原则·单一职责原则
性感博主在线瞎搞1 天前
【面向对象】设计模式概念和分类
设计模式·面向对象·中级软件设计师·设计方法
lucifer3111 天前
JavaScript 中的组合模式(十)
javascript·设计模式
lucifer3111 天前
JavaScript 中的装饰器模式(十一)
javascript·设计模式
蜡笔小新..1 天前
【设计模式】软件设计原则——依赖倒置&合成复用
设计模式·依赖倒置原则·合成复用原则