阅读 5

《Head First 设计模式》笔记-观察者模式

欢迎关注我的公众号:月光自习室

1.定义

观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

2.例子

考虑这样一个场景,气象站实时收集到一些气象数据,当气象数据更新后,希望展示气象数据的看板也跟着更新。

首先,建立一个 Observer 接口,表示观察者,当主题发生改变时会调用 update 方法。

public interface Observer {
    public void update(float temp, float humidity, float pressure);
}
复制代码

然后建立一个 Subject 接口,表示一个信息的发布者。

public interface  Subject {
    public void registerObserver(Observer observer);
    public void removeObserver(Observer observer);
    public void notifyObserver();
}
复制代码

registerObserver方法为这个主题添加观察者。

removeObserver方法移除观察者。

notifyOberver方法通知观察者调用对应的更新方法。

气象数据主题可以实现该接口以到达自己想要的效果。

public class WeatherData implements Subject {
    private ArrayList observers;
    private float temp;
    private float humidity;
    private float pressure;

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

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

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

    @Override
    public void notifyObserver() {
        for (Object observer : observers) {
            Observer ob = (Observer) observer;
            ob.update(temp, humidity, pressure);
        }
    }

    public void measurementChanged() {
        notifyObserver();
    }

    public void setMeasurements(float temp, float humidity, float pressure) {
        this.temp = temp;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementChanged();
    }
}
复制代码

然后就可以设计看板类,根据天气数据来展示信息,需求不同可以实现不同的看板类,只要实现 Observer 接口即可。

public class CurrentConditionsDisplay implements Observer {
    private Subject weatherData;
    private float humidity;
    private float temperature;
    
    public CurrentConditionsDisplay(Subject weatherData) {
        this.weatherData = weatherData;
    }
    
    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature = temp;
        this.humidity = humidity;
        display();
    }
    
    public void display() {
        System.out.println("CurrentConditionsDisplay{" +
                "humidity=" + humidity +
                ", temperature=" + temperature +
                '}');
    }
}
复制代码

这样就完成了一个简单的观察者模式,使用一下看看。

WeatherData weatherData = new WeatherData();
Observer observer1 = new CurrentConditionsDisplay(weatherData);
Observer observer2 = new CurrentConditionsDisplay(weatherData);
weatherData.registerObserver(observer1);
weatherData.registerObserver(observer2);
weatherData.setMeasurements(30.0f, 20.0f, 10.0f);
复制代码

这样就将多个观察者和一个主题关联起来,增加观察者也不会影响主题。

也可以不自己实现观察者模式,在 Java 中内置了观察者模式的实现,在 Util 包中的 Observer 接口和 Observable 类,可以自己根据需要扩展

3.设计原则

  • 类应该对扩展开放,对修改关闭
关注下面的标签,发现更多相似文章
评论