天气预报项目需求,具体要求如下:
- 气象站可以将每天测量到的温度,温度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方)。
- 需要设计开放型API,便于其他第三方也能接入气象站获取数据
- 提供温度、气压和温度的接口
- 测量数据更新时,要能实时的通知给第三方
public class WeatherData {
private float temperature;
private float pressure;
private float humidity;
private CurrentConditions currentConditions;
public WeatherData(CurrentConditions currentConditions) {
this.currentConditions = currentConditions;
}
public void dataChange(){
currentConditions.update(getTemperature(),getPressure(),getHumidity());
}
public float getTemperature(){
return temperature;
}
public float getPressure() {
return pressure;
}
public float getHumidity() {
return humidity;
}
public void setData(float temperature,float pressure,float humidity){
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
//调用dataChange,将最新的信息推送给接收方currentConditions
dataChange();
}
}
public class CurrentConditions {
//温度、气压、水温
private float temperature;
private float pressure;
private float humidity;
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
//显示
public void display() {
System.out.println("***Today mTemperature: " + temperature + "***");
System.out.println("***Today mPressure: " + pressure + "***");
System.out.println("***Today mHumidity: " + humidity + "***");
}
}
public class Client {
public static void main(String[] args) {
//创建接入方currentConditions
CurrentConditions currentConditions = new CurrentConditions();
//创建WeatherData 并将接入方currentConditions 传递到 WeatherData中
WeatherData weatherData = new WeatherData(currentConditions);
//更新天气情况
weatherData.setData(10,150,40);
//天气情况变化
weatherData.setData(40,160,39);
}
}
测试:
image.png
气象站设计方案1-普通方案
问题分析
- 其它第三方接入气象站获取数据的问题
- 无法在运行时动态的添加第三方
- 违反了ocp(开闭原则)原则 => 观察者模式
// 在WeartherData中,当增加一个第三方,都需要创建一个对应的第三方的公告板对象,并加入到dataChange,不利于维护,也不是动态加入。
/**
* @program: DesignPattern
* @description: 由观察者实现
* @author: hmx
* @create: 2021-06-30 21:03
**/
public interface Observer {
void update(float temperature,float pressure, float humidity);
}
/**
* @program: DesignPattern
* @description:
* @author: hmx
* @create: 2021-06-30 21:04
**/
public class CurrentConditions implements Observer{
//温度、气压、水温
private float temperature;
private float pressure;
private float humidity;
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
//显示
public void display() {
System.out.println("***Today mTemperature: " + temperature + "***");
System.out.println("***Today mPressure: " + pressure + "***");
System.out.println("***Today mHumidity: " + humidity + "***");
}
}
/**
* @program: DesignPattern
* @description:
* @author: hmx
* @create: 2021-06-30 21:18
**/
public class BaiduSite implements Observer{
//温度、气压、水温
private float temperature;
private float pressure;
private float humidity;
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
display();
}
//显示
public void display() {
System.out.println("***baidu mTemperature: " + temperature + "***");
System.out.println("***baidu mPressure: " + pressure + "***");
System.out.println("***baidu mHumidity: " + humidity + "***");
}
}
/**
* @program: DesignPattern 让WeatherData实现
* @description:
* @author: hmx
* @create: 2021-06-30 21:02
**/
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
/**
* @program: DesignPattern
* @description:
* 核心类:
* 1. 包含最新的天气情况信息
* 2. 含有观察者集合,使用ArrayList管理
* 3. 当有数据更新时,就主动的调用 ArrayList,通知所有的(接入方)就看到最新的信息
*
* @author: hmx
* @create: 2021-06-30 20:38
**/
public class WeatherData implements Subject{
private float temperature;
private float pressure;
private float humidity;
//观察者集合
private ArrayList<Observer> observers;
public WeatherData() {
observers = new ArrayList<>();
}
public void dataChange(){
notifyObservers();
}
public float getTemperature(){
return temperature;
}
public float getPressure() {
return pressure;
}
public float getHumidity() {
return humidity;
}
public void setData(float temperature,float pressure,float humidity){
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
//调用dataChange,将最新的信息推送给接收方currentConditions
dataChange();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(this.temperature,this.pressure,this.humidity);
}
}
}
/**
* @program: DesignPattern
* @description:
* @author: hmx
* @create: 2021-06-30 21:13
**/
public class Client {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
//创建观察者
CurrentConditions currentConditions = new CurrentConditions();
//注册到weatherData
weatherData.registerObserver(currentConditions);
weatherData.registerObserver(new BaiduSite());
//测试
System.out.println("通知各个注册的观察者,看看信息");
weatherData.setData(10f,10f,10f);
}
}
image.png