设计模式(2)观察者模式

观察者模式在主题和观察者之间定义一个一对多的依赖关系,当主题发生变化的时候,就会通知依赖它的对象主题已经发生了变化。观察者可以订阅主题,也可以取消订阅,当它取消订阅之后,主题发生的任何改变都不会通知到它,除非它再次订阅主题。

这次举得一个例子是气象站和布告栏,气象站用来检测气候的变化,布告栏用来显示气候的变化,不同的布告栏显示不同,当气象站发生变化的时候,通知布告栏气候的变化。

 

 

气象站中有一个集合,存放订阅气象站的公告栏,当气象发生变化的时候,会遍历公告栏集合,通知它们发生了变化。

公告栏对象中,存放着他们订阅的气象站对象,用于取消订阅和添加订阅。

下面是自己写的代码示例

观察者接口

public interface Observer {
    /**
     * 更新状态
     *
     * @param temp     温度
     * @param humidity 湿度
     * @param pressure 气压
     */
    void update(float temp, float humidity, float pressure);

    /**
     * 描述
     */
    void display();
}

主题接口

public interface Subject {
    /**
     * 通知观察者
     */
    void notifyObserver();

    /**
     * 订阅主题
     * @param observer 观察者
     */
    void registerdObserver(Observer observer);

    /**
     * 取消订阅主题
     * @param observer 观察者
     */
    void removerObserver(Observer observer);
}

观察者1

public class CurrentConditionsDisplay implements Observer {
    /**
     * 温度
     */
    private float template;
    /**
     * 湿度
     */
    private float humidity;
    /**
     * 气压
     */
    private float pressure;

    private Subject subject;

    public CurrentConditionsDisplay(Subject subject) {
        this.subject = subject;
        this.subject.registerdObserver(this);
    }

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

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

观察者2

public class ForecastDisplay implements Observer {
    /**
     * 温度
     */
    private float template;
    /**
     * 湿度
     */
    private float humidity;
    /**
     * 气压
     */
    private float pressure;

    private Subject subject;

    public ForecastDisplay(Subject subject) {
        this.subject = subject;
        this.subject.registerdObserver(this);
    }

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

    @Override
    public void display() {
        System.out.println("Forecast: " + template + "F degrees and " + humidity + "% humidity and " + pressure + " pressure ");
    }
}

 主题

public class WeatherData implements Subject {

    /**
     * 温度
     */
    private float template;
    /**
     * 湿度
     */
    private float humidity;
    /**
     * 气压
     */
    private float pressure;
    /**
     * 观察者列表
     */
    private List<Observer> observers;

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

    /**
     * 通知观察者
     */
    @Override
    public void notifyObserver() {
        for (Observer observer : observers) {
            observer.update(template, humidity, pressure);
        }
    }

    /**
     * 订阅主题
     *
     * @param observer 观察者
     */
    @Override
    public void registerdObserver(Observer observer) {
        observers.add(observer);
    }

    /**
     * 取消订阅主题
     *
     * @param observer 观察者
     */
    @Override
    public void removerObserver(Observer observer) {
        observers.remove(observer);
    }

    /**
     * 观测值发生改变
     *
     * @param template 温度
     * @param humidity 湿度
     * @param pressure 气压
     */
    public void setMeasurements(float template, float humidity, float pressure) {
        this.template = template;
        this.humidity = humidity;
        this.pressure = pressure;
        this.measurementsChange();
    }

    /**
     * 观测值发生改变
     */
    public void measurementsChange() {
        this.notifyObserver();
    }
}

测试

public class Main {

    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
        ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
        weatherData.setMeasurements(10.1f, 20.2f, 30.3f);
        weatherData.setMeasurements(11.1f, 22.2f, 33.3f);
        weatherData.removerObserver(currentConditionsDisplay);
        weatherData.setMeasurements(11.11f, 22.22f, 33.33f);
    }
}

输出

 

当创建观察者的时候,就将其订阅主题,每次主题发生改变,两个观察者都会接收到主题变化的通知。当观察者取消订阅主题后,主题的改动就不会通知到观察者了。

观察者模式可以运用到很多地方,最常见的就是邮件或者博客的订阅,当你订阅了这个博客之后,每当有文章更新就会及时通知你。

 

posted @ 2019-02-21 21:16  oeleven  阅读(176)  评论(0编辑  收藏  举报