HeadFirst 观察者模式(observer)

使用目的

降低交互对象的耦合度

定义

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

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 。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值