观察者模式

观察者模式 = 出版者(主题) + 订阅者(观察者)

  1、主题对象管理某些数据

  2、当主题内的数据改变就会通知观察者

  3、观察者已经订阅(注册)主题以便在主题数据改变时能够收到更新

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

设计原则:

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

 

案例代码:

/**
 * 主题接口
 *
 * @author guoxin
 */
public interface Subject {
    /**
     * 注册观察者
     *
     * @param o 观察者接口
     */
    void registerObserver(Observer o);

    /**
     * 注销观察者
     *
     * @param o 观察者接口
     */
    void removeObserver(Observer o);

    /**
     * 当主题状态改变时,这个方法会被调用,以通知所有的观察者
     */
    void notifyObserver();
}
/**
 * 观察者接口
 *
 * @author guoxin
 */
public interface Observer {
    /**
     * 跟新数据
     *
     * @param temp     温度
     * @param humidity 湿度
     * @param pressure 压力
     */
    void update(float temp, float humidity, float pressure);
}
/**
 * 数据显示接口
 *
 * @author guoxin
 */
public interface DisplayElement {
    void display();
}
import java.util.ArrayList;
import java.util.List;

/**
 * 气象数据类
 *
 * @author guoxin
 */
public class WeatherData implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

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

    /**
     * 注册观察者
     *
     * @param o 观察者接口
     */
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    /**
     * 注销观察者
     *
     * @param o 观察者接口
     */
    @Override
    public void removeObserver(Observer o) {
        if (observers.contains(o)) {
            observers.remove(o);
        }
    }

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

    /**
     * 当从气象站得到更新观测值时,我们通知观察者
     */
    public void measurementsChanged() {
        notifyObserver();
    }

    /**
     * 设置数据
     *
     * @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();
    }
}
/**
 * 当前气象面板
 *
 * @author guoxin
 */
public class CurrentConditionDisplay implements Observer, DisplayElement {
    private float temperature;
    private float humidity;
    private Subject subject;

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

    @Override
    public void display() {
        System.out.println("current conditions: " + temperature + "F degree and " + humidity + "% humidity");
    }

    /**
     * 当update()被调用时,我们把温度和湿度保存起来,然后调用display()。
     *
     * @param temp     温度
     * @param humidity 湿度
     * @param pressure 压力
     */
    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature = temp;
        this.humidity = humidity;
        display();
    }
}

 

/**
 * 酷热面板
 *
 * @author guoxin
 */
public class HeatIndexDisplay implements Observer, DisplayElement {
    private float temperature;
    private float humidity;
    private Subject subject;

    public HeatIndexDisplay(Subject subject) {
        this.subject = subject;
        subject.registerObserver(this);
    }

    @Override
    public void display() {
        float heat = computeHeatIndex(temperature, humidity);
        System.out.println("health index is " + heat);
    }

    /**
     * 当update()被调用时,我们把温度和湿度保存起来,然后调用display()。
     *
     * @param temp     温度
     * @param humidity 湿度
     * @param pressure 压力
     */
    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature = temp;
        this.humidity = humidity;
        display();
    }

    /**
     * 计算酷热指数
     *
     * @param t  温度
     * @param rh 湿度
     * @return 酷热指数
     */
    private float computeHeatIndex(float t, float rh) {
        return (float) ((16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh) +
                (0.00941695 * (t * t)) + (0.00728898 * (rh * rh)) +
                (0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh)) +
                (0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t)) + (0.0000291583 *
                (rh * rh * rh)) + (0.00000142721 * (t * t * t * rh)) +
                (0.000000197483 * (t * rh * rh * rh)) - (0.0000000218429 * (t * t * t * rh * rh)) +
                0.000000000843296 * (t * t * rh * rh * rh)) -
                (0.0000000000481975 * (t * t * t * rh * rh * rh)));
    }

}

 

/**
 * 测试类
 *
 * @author guoxin
 */
public class WeatherStation {
    public static void main(String[] args) {
        WeatherData wd = new WeatherData();
        CurrentConditionDisplay ccd = new CurrentConditionDisplay(wd);
        HeatIndexDisplay hid = new HeatIndexDisplay(wd);
        wd.setMeasurements(80, 65, 30.4f);
        wd.setMeasurements(82, 70, 29.2f);
    }
}

 

类图:

 

 

posted @ 2019-01-16 22:36  郭鑫  阅读(188)  评论(0编辑  收藏  举报