HeadFirst 观察者模式(observer)

来源:互联网 发布:淘宝人工客服旺旺 编辑:程序博客网 时间:2024/06/05 19:20

使用目的

降低交互对象的耦合度

定义

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

1对多的关系 ,1 是被观察者(主题),多是观察者。观察者通过订阅主题,以便在主题数据发生变化时,收到更新。

生活中的例子

以报纸或杂志的订阅分析
1.报社的业务出版报纸。
2.订阅某家报社的报纸后,只要报社出新报纸,就会给你送来,只要你是他的客户,就会源源不断收到新报纸。
3.当你不想看报纸的时候,只要取消订阅,那就不会再收到新的报纸。
4.只要报社还在运营,就会不断地有个人或单位订阅或取消订阅报纸。

通过图的方式描述观察者和被观察者的关系:

这里写图片描述

类图关系

这里写图片描述



实际应用

下面以气象站天气预报为例介绍观察者模式具体使用
我们要实现一个从气象站获取信息,实现目前状况(温度,湿度,气压)、气象统计、天气预报 三个功能的应用

类图关系应该是这样的:
这里写图片描述

首先是主题与观察者接口

public interface Subject {    /**     * 观察者与被观察者建立依赖关系     * @param o     */    public void registerObserver(Observer o);    /**     * 取消观察者与被观察者的依赖关系     * @param o     */    public void removeObserver(Observer o);    /**     * 数据更新通知观察者     */    public void notifyObservers();}
public interface Observer {    /**     * 所有的气象组件观察者实现此接口,这样当主题通知观察者时,有了一个共同的接口     * @param temp     * @param humidity     * @param pressure     */    void update(float temp,float humidity,float pressure);}

接下来是具体的 Subject 气象数据:

public class WeatherData implements Subject {    private ArrayList observers;    private float temperature;    private float humidity;    private float pressure;    public WeatherData(){        observers = new ArrayList();    }    /**     * 将观察者与自身建立依赖关系     */    public void registerObserver(Observer o) {        // TODO Auto-generated method stub        observers.add(o);    }    /**     * 将观察者与自身解除依赖关系     */    public void removeObserver(Observer o) {        // TODO Auto-generated method stub        int i = observers.indexOf(o);        if(i >= 0){            observers.remove(i);        }    }    public void notifyObservers() {        // TODO Auto-generated method stub        for(int i = 0;i < observers.size(); i++){            Observer observer = (Observer) observers.get(i);            observer.update(temperature, humidity, pressure);        }    }    public void measurementsChanged(){        notifyObservers();    }    /**     * 取到最新的温度 湿度 气压时,会发出测量数据改变,通知观察者     * @param temperature     * @param humidity     * @param pressure     */    public void setMeasurements(float temperature,float humidity,float pressure){        this.temperature = temperature;        this.humidity = humidity;        this.pressure = pressure;        measurementsChanged();    }    //other method}

举例以当前状况作为观察者的具体实现

/** * 目前状况 温度 湿度 气压 * @author admin * */public class CurrentConditionsDisplay implements Observer,DisplayElement{    private float temperature;    private float humidity;    private Subject weatherData;    public CurrentConditionsDisplay(Subject weatherData){        this.weatherData = weatherData;        //注册依赖        weatherData.registerObserver(this);    }    public void display() {        // TODO Auto-generated method stub        System.out.println("Current conditions:"+temperature +"F degrees and "+                humidity+"% humidity");    }    /**     * 接收到 Subject 发来的数据更新     */    public void update(float temp, float humidity, float pressure) {        // TODO Auto-generated method stub        this.temperature = temp;        this.humidity = humidity;        display();    }}
/** * 观察者模式 * @author admin * */public class WeatherStation {    public static void main(String[] args) {        // TODO Auto-generated method stub        WeatherData weatherData = new WeatherData();        CurrentConditionsDisplay conditionsDisplay =                new CurrentConditionsDisplay(weatherData);//      ForecastDisplay forecastDisplay =//              new ForecastDisplay(weatherData);        weatherData.setMeasurements(80, 65, 30.4f);        weatherData.setMeasurements(82, 70, 29.2f);        weatherData.setMeasurements(78, 90, 29.2f);    }}
public interface DisplayElement {    void display();}

这样,就实现了观察者模式使用。

Java 本身实现了观察者模式, 具体可以查看import java.util.Observable;和import java.util.Observer;




PS

欢迎爱学习的小伙伴加群一起进步:230274309 。

一起分享,一起进步!少划水,多晒干货!!欢迎大家!!!(进群潜水者勿加)

原创粉丝点击