写点什么

设计模式学习 -- 观察者模式 (Observer Pattern)

用户头像
Android架构
关注
发布于: 8 小时前

this.temperature = temperature;


this.humidity = humidity;


this.pressure = pressure;


measurementsChanged();


}


}


5. 定义四个布告板类实现观察者接口和布告板接口


package observerPattern;


/**


  • 观察者类实现观察者接口和显示板接口

  • @author wwj


*/


public class CurrentConditionDisplay implements Observer, DisplayElement {


private float temperature;


private float humidity;


private Subject weathderData;


public CurrentConditionDisplay(Subject weathderData) {


this.weathderData = weathderData;


weathderData.registerObserver(this); //注册


}


@Override


public void display() {


System.out.println("Current coditions: " + temperature + "F degress and " + humidity + "% humidity");


}


@Override


public void update(float temp, float humidity, float pressure) {


this.temperature = temp;


this.humidity = humidity;


display();


}


}


package observerPattern;


/**


  • 天气统计布告板

  • @author wwj


*/


public class StatisticsDisplay implements Observer, DisplayElement {


private float maxTemp = 0.0f;; //最大温度


private float minTemp = 200; //最小温度


private float tempSum = 0.0f; //统计温度和


private int numReadings; //统计温度次数


private WeatherData weatherData;


public StatisticsDisplay(WeatherData weatherData) {


this.weatherData = weatherData;


weatherData.registerObserver(this);


}


@Override


public void display() {


System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings) + "/" + maxTemp + "/" + minTemp);


}


@Override


public void update(float temp, float humidity, float pressure) {


tempSum += temp;


numReadings++;


if(temp > maxTemp) {


maxTemp = temp;


}


if(temp < minTemp) {


minTemp = temp;


}


display();


}


}


package observerPattern;


/**


  • 天气预报布告板

  • @author wwj


*/


public class ForecastDisplay implements Observer, DisplayElement {


private float currentPressure = 29.92f; //当前气压


private float lastPressure; //以往气压


private WeatherData weatherData;


public ForecastDisplay(WeatherData weatherData) {


this.weatherData = weatherData;


weatherData.registerObserver(this);


}


@Override


public void display() {


System.out.println("Forcast:");


if(currentPressure > lastPressure) {


System.out.println("Improving weather on the way!");


} else if(currentPressure == lastPressure) {


System.out.println("more of the same");


} else if(currentPressure < lastPressure) {


System.out.println("Watch out for cooler, rainy weather");


}


}


@Override


public void update(float temp, float humidity, float pressure) {


lastPressure = currentPressure;


currentPressure = pressure;


display();


}


}


package observerPattern;


/**


  • 酷热指数布告板

  • @author wwj

  • 注:那个计算酷热指数的公式不必深究


*/


public class HeatIndexDisplay implements Observer, DisplayElement {


float heatIndex = 0.0f;


private WeatherData weatherData;


public HeatIndexDisplay(WeatherData weatherData) {


this.weatherData = weatherData;


weatherData.registerObserver(this);


}


public void update(float t, float rh, float pressure) {


heatIndex = computeHeatIndex(t, rh);


display();


}


private float computeHeatIndex(float t, float rh) {


float index = (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)));


return index;


}


public void display() {


System.out.println("Heat index is " + heatIndex);


}


}


6. 来吧,开始测试


package observerPattern;


/**


  • 测试类

  • @author wwj


*/


public class WeatherStation {


public static void main(String[] args) {


//建立一个 WeatherData 对象


WeatherData weatherData = new WeatherData();


//第一个布告板


CurrentConditionDisplay currentDisplay = new CurrentConditionDisplay(


weatherData);


StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);


ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);


HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData);


// 模拟新的气象数据


weatherData.setMeasurements(80, 65, 30.4f);


weatherData.setMeasurements(82, 70, 29.2f);


weatherData.setMeasurements(78, 90, 29.2f);


}


}


7. 测试结果:


Current coditions: 80.0F degress and 65.0% humidity


Avg/Max/Min temperature = 80.0/80.0/80.0


Forcast:


Improving weather on the way!


Heat index is 82.95535


Current coditions: 82.0F degress and 70.0% humidity


Avg/Max/Min temperature = 81.0/82.0/80.0


Forcast:


Watch out for cooler, rainy weather


Heat index is 86.90124


Current coditions: 78.0F degress and 90.0% humidity


Avg/Max/Min temperature = 80.0/82.0/78.0


Forcast:


more of the same


Heat index is 83.64967


以上的观察者模式实现是通过主题以“推”的方式通知观察者们,观察者可以在一次通知中一口气得到所有东西。


因为观察者与主题发生了争吵,观察者有自己的想法,希望能“拉”走主题的状态,然而 Java 内置的 Observer 模式就支持这样,下面来看看吧。


1. 继承 Observable 类的 WeatherData(不再需要自定义接口了,但这样真的好吗?)


package weatherObservable;


import java.util.Observable;


/**


  • 使用 Java 内置的观察者模式

  • @author wwj


*/


public class WeatherData extends Observable {


private float temperature;


private float humidity;


private float pressure;


/**


  • 我们的构造器不再需要为了记住观察者们而建立数据结构了


*/


public WeatherData(){}


public void measurementsChanged() {


setChanged(); //Observable 类方法


notifyObservers();


}


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;


}


}


2. 4 个布告板中的代码稍微发生了点变化


package weatherObservable;


import java.util.Observable;


import java.util.Observer;


/**


  • 实现 Java 内置的观察者接口,布告板不变

  • @author wwj


*/


public class CurrentConditionDisplay implements Observer, DisplayElement{


Observable observable;


private float temperature;


private float humidity;


public CurrentConditionDisplay(Observable observable) {


this.observable = observable;


observable.addObserver(this); //登记为观察者


}


@Override


public void display() {


System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");


}


/**


  • 在这个方法当中,先确定可观察者属于 WeatherData 类型,然后利用 getter 方法获取温度和温度测量值,最后调用 display();


*/


@Override


public void update(Observable obs, Object arg) {


if(obs instanceof WeatherData) {


WeatherData weatherData = (WeatherData) obs;


this.temperature = weatherData.getTemperature();


this.humidity = weatherData.getHumidity();


display();


}


}


}


package weatherObservable;


import java.util.Observable;


import java.util.Observer;


/**


  • 天气预报布告板

  • @author wwj


*/


public class ForecastDisplay implements Observer, DisplayElement {


private Observable observable;


private float currentPressure = 29.92f; //当前气压


private float lastPressure; //以往气压


public ForecastDisplay(Observable observable) {


this.observable = observable;


observable.addObserver(this);


}


@Override


public void display() {


System.out.println("Forcast:");


if(currentPressure > lastPressure) {


System.out.println("Improving weather on the way!");


} else if(currentPressure == lastPressure) {


System.out.println("more of the same");


} else if(currentPressure < lastPressure) {


System.out.println("Watch out for cooler, rainy weather");


}


}


@Override


public void update(Observable o, Object arg) {


if (o instanceof WeatherData) {


WeatherData weatherData = (WeatherData)observable;


lastPressure = currentPressure;


currentPressure = weatherData.getPressure();


display();


}


}


}


package weatherObservable;


import java.util.Observable;


import java.util.Observer;


/**


  • 天气统计布告板

  • @author wwj


*/


public class StatisticsDisplay implements Observer, DisplayElement {


private float maxTemp = 0.0f;; //最大温度


private float minTemp = 200; //最小温度


private float tempSum = 0.0f; //统计温度和


private int numReadings; //统计温度次数


private Observable observable;


public StatisticsDisplay(Observable observable) {


this.observable = observable;


observable.addObserver(this);


}


@Override


public void display() {


System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings) + "/" + maxTemp + "/" + minTemp);


}


@Override


public void update(Observable obs, Object arg) {


if(obs instanceof WeatherData) {


WeatherData weatherData = (WeatherData)obs;


float temp = weatherData.getTemperature();


tempSum += temp;


numReadings++;


if (temp > maxTemp) {


maxTemp = temp;


}


if (temp < minTemp) {


minTemp = temp;


}


display();


}


}


}


package weatherObservable;


import java.util.Observable;


import java.util.Observer;


/**


  • 酷热指数布告板

  • @author wwj

  • 注:那个计算酷热指数的公式不必深究


*/


public class HeatIndexDisplay implements Observer, DisplayElement {


float heatIndex = 0.0f;


private WeatherData weatherData;


private Observable observable;


public HeatIndexDisplay(Observable observable) {


this.observable = observable;


observable.addObserver(this);


}


private float computeHeatIndex(float t, float rh) {


float index = (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)));


return index;


}


public void display() {


System.out.println("Heat index is " + heatIndex);


}


@Override


public void update(Observable obs, Object arg) {


if(obs instanceof WeatherData) {


WeatherData weatherData = (WeatherData)observable;


float t = weatherData.getTemperature


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


();


float rh = weatherData.getHumidity();


heatIndex = computeHeatIndex(t, rh);


}


display();


}


}


3. 测试类不变


package weatherObservable;


/**


  • 测试类

  • @author wwj


*/


public class WeatherStation {


public static void main(String[] args) {


//建立一个 WeatherData 对象


WeatherData weatherData = new WeatherData();


//第一个布告板


CurrentConditionDisplay currentDisplay = new CurrentConditionDisplay(


weatherData);


StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);


ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);


HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData);

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
设计模式学习--观察者模式(Observer Pattern)