观察者设计模式

模式定义

观察者设计模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时会通知全部的观察者对象使他们可以自动更新本身。java

类图定义

示例

气象站的温度,气压等数据变化后要推送到不一样的统计面板。这里的主题也就是被观察者就是气象站的各类数据的对象,不一样的观察者也就是不一样的显示的面板。首先定义好主题和观察者接口,主题接口主要注册移除和通知观察者,观察者接口则须要提供统一的更新本身数据的方法,在主题发生数据变化时能够统一进行调用处理。设计模式

/**
 * 主题接口
 *
 * @author Colin
 * @create 2018-03-13
 **/
public interface Subject {

    /**
     * 注册观察者
     * @param o
     */
    public void registerObserver(Observer o);

    /**
     * 移除观察者
     * @param o
     */
    public void removeObserver(Observer o);

    /**
     * 通知观察者
     */
    public void notifyObserver();
}

/**
 * 观察者
 *
 * @author Colin
 * @create 2018-03-13
 **/
public interface Observer {
    /**
     * 更新实时信息
     * @param temp
     * @param humidity
     * @param pressure
     */
    public void update(float temp,float humidity,float pressure);
}

/**
 * 显示接口
 *
 * @author Colin
 * @create 2018-03-13
 **/
public interface DisplayElement {
    /**
     * 显示方法
     */
    public void display();
}

主题和观察者具体实现类,主题中提供数据变化方法,当数据发生变化时 ,遍历注册的观察者调用观察者的更新数据方法实现通知。ide

/**
 * 气象数据对象(即主题)
 *
 * @author Colin
 * @create 2018-03-13
 **/
public class WeatherData implements Subject {

    private List<Observer> observers;
    private float temp;
    private float humidity;
    private float pressure;
    public WeatherData(){
        observers=new ArrayList<Observer>();
    }

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

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

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

    public void measurementsChanged(){
        notifyObserver();
    }

    public void setMeasurements(float temp,float humidity,float pressure){
        this.temp=temp;
        this.humidity=humidity;
        this.pressure=pressure;
        notifyObserver();
    }
}

/**
 * 即时面板显示
 *
 * @author Colin
 * @create 2018-03-13
 **/
public class CurrentConditionDisplay implements Observer,DisplayElement {

    private float temp;
    private float humidity;
    private Subject weatherData;

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

    @Override
    public void display() {
        System.out.println("当前温度:"+temp+",当前湿度:"+humidity);
    }

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

示例(java版本的观察者模式)

java中提供Observable类做为主题的父类,Observer 做为观察者接口this

/**
 * 主题
 *
 * @author Colin
 * @create 2018-03-14
 **/
public class WeatherDataJava extends Observable{

    private float temp;
    private float humdity;
    private float pressure;

    public WeatherDataJava(){}

    public void  measurementsChanged(){
        setChanged();
        notifyObservers();
    }

    public void setMeasurementsChanges(float temp,float humidity,float pressure){
        this.temp=temp;
        this.humdity=humidity;
        this.pressure=pressure;
        measurementsChanged();
    }

    public float getTemp() {
        return temp;
    }

    public void setTemp(float temp) {
        this.temp = temp;
    }

    public float getHumdity() {
        return humdity;
    }

    public void setHumdity(float humdity) {
        this.humdity = humdity;
    }

    public float getPressure() {
        return pressure;
    }

    public void setPressure(float pressure) {
        this.pressure = pressure;
    }
}
**
 * 具体观察者
 *
 * @author Colin
 * @create 2018-03-14
 **/
public class CurrentConditionDisplayJava implements Observer ,DisplayElement{

    private Observable observer;

    private float temp;
    private float humidity;
    private float pressure;

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

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof WeatherDataJava){
            WeatherDataJava weatherDataJava=(WeatherDataJava) o;
            this.temp=weatherDataJava.getTemp();
            this.humidity=weatherDataJava.getHumdity();
            this.pressure=weatherDataJava.getPressure();
            display();
        }
    }

    @Override
    public void display() {
        System.out.println("温度:"+temp+",湿度:"+humidity+",压力:"+pressure);
    }
}

总结

  • 观察者模式的应用场景:当一个对象改变时须要通知到其余对象,并且不知道有多少其余对象的时候考虑使用。
  • 观察者模式所作的工做其实就是在解除耦合,解除主题对象和具体观察者之间的耦合性,当观察者发生发生变化时不会影响的其余的变化。设计

    涉及到的设计原则code

  • 为交互对象之间的松耦合设计而努力server

相关文章
相关标签/搜索