观察者模式

1 天气预报需求

气象站可以实时测量当前的温度、湿度等数据并以公告的形式发布出去。现在需要设计一个开放型API接口便于第三个接入并获取到气象站的数据,要求提供温度、湿度的接口,测量的数据要实时通知给第三方。下面我们有观察者模式来实现这个需求。

2 观察者模式介绍

观察者模式是对象之间多对一依赖的一种设计方案,被依赖的对象是Subject,依赖的对象是Observer,Subject通知Observer变化。
角色分析:
Subject:负责登记注册、移出观察者,当有数据变化时,通知到已注册的观察者。
Observer:需要去Subject注册,注册后可以接收到Subject的通知。


观察者模式的类图

3 用观察者模式实现需求

首先定义Subject和Observer:

public interface Subject {
    void registerObserver(Observer observer);

    void unregisterObserver(Observer observer);

    void notifyObservers();
}
// 观察者接口,由观察者实现
public interface Observer {
    void update(float temperature, float humidity);
}

气象站实现类WeatherData,实现了Subject:

public class WeatherData implements Subject {
    private float temperature;
    private float humidity;
    // 观察者集合
    private List<Observer> observers;

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

    public void setData(float temperature, float humidity) {
        this.temperature = temperature;
        this.humidity = humidity;
        // 更新完数据后通知所有观察者
        notifyObservers();
    }

    public float getTemperature() {
        return temperature;
    }

    public void setTemperature(float temperature) {
        this.temperature = temperature;
    }

    public float getHumidity() {
        return humidity;
    }

    public void setHumidity(float humidity) {
        this.humidity = humidity;
    }

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

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

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

观察者实现类有两个,一个是气象站自己的官网,另一个是百度天气:

public class WeatherObserver implements Observer {
    private float temperature;
    private float humidity;

    @Override
    public void update(float temperature, float humidity) {
        this.temperature = temperature;
        this.humidity = humidity;
        display();
    }

    private void display() {
        System.out.println("当前温度:" + temperature + ", 湿度:" + humidity);
    }
}
public class BaiduObserver implements Observer {
    @Override
    public void update(float temperature, float humidity) {
        System.out.println("百度天气:当前温度:" + temperature + ", 湿度:" + humidity);
    }
}

客户端调用:

public class Client {
    public static void main(String[] args) {
        // 创建一个WeatherData对象
        WeatherData weatherData = new WeatherData();

        // 创建观察者
        Observer observer1 = new WeatherObserver();
        Observer observer2 = new BaiduObserver();
        // 注册到weatherData中
        weatherData.registerObserver(observer1);
        weatherData.registerObserver(observer2);

        // 天气更新了
        System.out.println("===========================");
        weatherData.setData(28.5f, 45.0f);
    }
}

运行结果:

===========================
当前温度:28.5, 湿度:45.0
百度天气:当前温度:28.5, 湿度:45.0
天气预报需求类图

4 观察者模式的特点

观察者模式会以集合的方式来管理观察者,包括注册、移出和通知,这样的好处是:如果增加观察者,就不需要去修改核心类(WeatherData),符合ocp原则。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容