观察者模式


有了观察者你将消息灵通。


气象监测应用的概况
此系统中的三个部分是:
气象站——获取实际气象数据的物理装置
WeatherData对象——追踪来自气象站的数据,并更新布告板
布告板——显示目前天气状况给用户看

出版者+订阅者=观察者模式
主题(Subject)+观察者(Observer)
说明:
1. 主题对象管理某些数据
2. 当主题内数据改变,就会通知观察者。
3. 一旦数据改变,新的数据会以某种形式送到观察者手上
4. 观察者已经订阅(注册)主题以便在主题数据改变时能够收到更新

当你试图勾勒观察者模式时,可以利用报纸订阅服务,以及出版者和订阅者比拟这一切。观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。有多个观察者时,不可以依赖特定的通知次序。
这里写图片描述
说明:

  1. Subject——主题接口,对象使用此接口注册为观察者,或者把自己从观察者中删除。
  2. 每个Subject可以有许多观察者
  3. Observer——所有潜在的观察者必须实现观察者接口,这个接口只有update方法,当主题状态改变时它被调用。
  4. ConcreteSubject ——一个具体主题总是实现主题接口,除了注册和撤销方法之外,具体主题还实现了notifyObservers()方法,此方法用于在状态改变时更新所有当前观察者。具体主题也可能有设置和获取状态的方法。
  5. ConcreteObserver——具体的观察者可以是实现此接口的任意类。观察者必须注册具体主题,以便接收更新。

设计原则——为了交互对象之间的松耦合设计而努力。
松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的相互依赖降到了最低。

实现气象站

public interface Subject{
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObservers();
    //当主题状态改变时,这个方法会被调用,以通知所有的观察者
}
public interface Observer{
    public void update(float temp,float humidity,float pressure);
    //当气象观测值改变时,主题会把这些状态值当作方法的参数,传递给观察者
}
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){
        observers.add(o);
    }

    public void removeObserver(Observer o){
        int i = observers.indexOf(o);
        if(i>=0){
            observers.remove(i);
        }
    }

    public void notifyObservers(){
        for(int i = 0; i < observers.size();i++){
            Observer observer = (Observer)observers.get(i);
            observer.update(temperature,humidity,pressure);
        }
    }

    public void measurementsChanged(){
        notifyObservers();
    }

    public void setMeasurements(float temperature,float humidity,float pressure){
    this.temperature = temperature;
    this.humidity = humidity;
    this.pressure = pressure;
    measurementsChanged();
    }
public class CurrentConditionsDisplay implements Observer{
    private float temperature;
    private float humidity;
    private Subject weatherData;

    public CurrentConditionsDisplay(Subject weatherData){
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }

    public void update(float temperature,float humidity,float pressure){
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
    }
}

Java内置观察者模式
Observer接口和Obserable接口
这里写图片描述

Observable是一个“类”,而不是一个接口,所以WeatherData扩展了Observable主题。

  1. 如何把对象变成观察者。调用任何Observable对象的addObserver()方法。不想再当观察者时,调用deleteObserver()方法就可以了。
  2. 观察者如何送出通知。先调用setChanged()方法,标记状态已经改变哦事实;然后调用两种notifyObservers方法中的一个。
  3. 观察者如何接收通知。update(Observable o,Object arg)
public class WeatherData extends Observable{
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData(){ }
    public void measurementsChanged(){
        setChanged();
        notifyObservers();//采用的做法是“拉”  
        //notifyObservers(arg)是“推”
    }

    public void setMeasurements(float temperature,float humidity,float pressure){
    this.temperature = temperature;
    this.humidity = humidity;
    this.pressure = pressure;
    measurementsChanged();
    }

    public float getTemperature(){
        return temperature;
    }

    public float getHumidity(){
        return humidity;
    }

    public float getPressure(){
        return pressure;
    }
}
public class CurrentConditionsDisplay implements Observer{
    Observable observable;
    private float temperature;
    private float humidity;

    public CurrentConditionsDisplay(Observable observable){
        this.observable = observable;
        observable.addObserver(this);
    }

    public void update(Observable obs,Object arg){
        if(obs instanceof WeatherData){
            WeatherData weatherData = (WeatherData)obs;
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值