博主的博客地址: https://www.jeffcc.top/ 博主学习设计模式用的书是Head First的《设计模式》,强烈推荐配套使用!
package tag;
import observer.Observer;
/**
* 主题需要实现的接口规范
*/
public interface Subject {
// 注册观察者
public void registerObserver(Observer observer);
// 注销观察者
public void removeObserver(Observer observer);
// 主题发生变化的时候 通知在注册的观察者
public void notifyObserver();
}
package tag.impl;
import observer.Observer;
import tag.Subject;
import java.util.ArrayList;
/**
* 主题的实现类
*/
public class WeatherDate implements Subject {
// 用于存储观察者的集合
private ArrayList<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
/**
* 初始化集合!很重要!
*/
public WeatherDate() {
this.observers = new ArrayList<Observer>();
}
/**
* 注册观察者
* @param observer
*/
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
/**
*注销观察者
* @param observer
*/
@Override
public void removeObserver(Observer observer) {
// 注意防止非空
if(observers.indexOf(observer)>0){
observers.remove(observer);
}
}
/**
* 唤醒观察者
*/
@Override
public void notifyObserver() {
observers.forEach(observer -> {
observer.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();
}
}
package observer;
/**
* 观察者需要实现的接口
*/
public interface Observer {
/**
* 实时更新的方法
* @param temp 温度
* @param humidity 湿度
* @param pressure 气压
*/
public void update(float temp, float humidity,float pressure);
}
package observer;
/**
* 布告板需要实现的类
*/
public interface DisplayElement {
/**
* 显示数据的方法
*/
public void display();
}
package observer.impl;
import observer.DisplayElement;
import observer.Observer;
import tag.Subject;
/**
* 第一个观察者
* 实时更新温度情况
*/
public class CurrentTemperatureDisplay implements Observer, DisplayElement {
private float temperature;
private Subject weatherDate;
/**
* 需要一个主题用来注册
* @param weatherDate
*/
public CurrentTemperatureDisplay(Subject weatherDate) {
this.weatherDate = weatherDate;
weatherDate.registerObserver(this);
}
/**
* 实时发布信息
*/
@Override
public void display() {
System.out.print("一号布告板:");
System.out.println("temperature:"+temperature);
}
/**
* 布告板更新
* @param temp 温度
* @param humidity 湿度
* @param pressure 气压
*/
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
display();
}
}
package observer.impl;
import observer.DisplayElement;
import observer.Observer;
import tag.Subject;
/**
* 第二个观察者
* 实时更新湿度情况
*/
public class CurrentHumidityDisplay implements Observer, DisplayElement {
private float humidity;
private Subject weatherDate;
/**
* 需要一个主题用来注册
* @param weatherDate
*/
public CurrentHumidityDisplay(Subject weatherDate) {
this.weatherDate = weatherDate;
weatherDate.registerObserver(this);
}
/**
* 实时发布信息
*/
@Override
public void display() {
System.out.print("二号布告板:");
System.out.println("humidity:"+humidity);
}
/**
* 布告板更新
* @param temp 温度
* @param humidity 湿度
* @param pressure 气压
*/
@Override
public void update(float temp, float humidity, float pressure) {
this.humidity = humidity;
display();
}
}
package observer.impl;
import observer.DisplayElement;
import observer.Observer;
import tag.Subject;
/**
* 第三个观察者
* 实时更新气压情况
*/
public class CurrentPressureDisplay implements Observer, DisplayElement {
private float pressure;
private Subject weatherDate;
/**
* 需要一个主题用来注册
* @param weatherDate
*/
public CurrentPressureDisplay(Subject weatherDate) {
this.weatherDate = weatherDate;
weatherDate.registerObserver(this);
}
/**
* 实时发布信息
*/
@Override
public void display() {
System.out.print("三号布告板:");
System.out.println("pressure:"+pressure);
}
/**
* 布告板更新
* @param temp 温度
* @param humidity 湿度
* @param pressure 气压
*/
@Override
public void update(float temp, float humidity, float pressure) {
this.pressure = pressure;
display();
}
}
package test;
import observer.impl.CurrentHumidityDisplay;
import observer.impl.CurrentPressureDisplay;
import observer.impl.CurrentTemperatureDisplay;
import tag.impl.WeatherDate;
/**
* 气象站测试
*/
public class WeatherDateTest {
public static void main(String[] args) {
// 新建一个气象站
WeatherDate weatherDate = new WeatherDate();
// 注册三个布告板
new CurrentTemperatureDisplay(weatherDate);
new CurrentHumidityDisplay(weatherDate);
new CurrentPressureDisplay(weatherDate);
// 模拟气象站发布新气象
weatherDate.setMeasurements(80,60,30.4f);
weatherDate.setMeasurements(40,30,20.1f);
weatherDate.setMeasurements(20,10,10.7f);
}
}