1.Internet气象站项目:
1.提供温度,气压和湿度的接口
2.测量数据更新时需要时通知给第三方
3.需要设计开放型API,便于其他公司的也能接入点气象站获取数据
2.WeatherDate类
WeatherData
getTemperature()
getHumidity()
getPressure()
dataChange()
3.气象站
当气象站监测到这些数据的变化的时候,就通知dataChange()函数。
方案一:通用的设计方案
1.设计一个公告板
CurrentConditions
updata()
display()
2.设计WeatherData类
WeatherDate
getTemperature()
getHumidity()
getPressure()
dataChange()
当dataChange() 接收到信息的变化的时候,就通知公告板的update()去通知更新数据
代码实现:
WeatherData
package com.java.Internetweather_1;
//相当于一个接口
public class WeatherData {
private float temperature;
private float humidity;
private float pressure;
//有了公告板后,我们就可以把它当作一个属性,被接口使用
private CurrentConditions currentConditions;
public WeatherData(CurrentConditions currentConditions) {
this.currentConditions = currentConditions;
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
public void dataChange() {
//当公告板有信息后,我们就调用它
//temperature, pressure, humidity都是从气象站获取的,所以用get()方法,然后传给公告板的
currentConditions.updata(getTemperature(),getPressure(), getPressure());
}
//假设气象站有数据变化setData()模拟了气象站,有数据变化并告诉weatherdata有新数据了,然后waetherdata进行数据的更新();
public void setData(float temperature, float pressure,float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
dataChange();
}
}
公告板类:CurrentConditions
package com.java.Internetweather_1;
public class CurrentConditions {
private float temperature;
private float pressure;
private float humidity;
public void updata( float temperature, float pressure,float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
//当有更新的时候,我们就直接显示
display();
}
public void display() {
System.out.println("****Taday temperature : "+temperature+"****");
System.out.println("****Taday pressure: "+pressure+"****");
System.out.println("****Taday humiduty: "+humidity+"****");
}
}
测试类:InternetWeather
package com.java.Internetweather_1;
public class InternetWeather {
public static void main(String[] args) {
InternetWeather internetWeather = new InternetWeather();
}
public InternetWeather() {
CurrentConditions currentconditions = new CurrentConditions() ;
WeatherData weatherData = new WeatherData(currentconditions) ;
weatherData.setData(16, 160, 20);
}
}
问题:当其他公司也需要气象站的消息,也想要做一个公告板的时候,我们需要在weatherdata类中的大它 change() 里加入其他公告板的初始化;每增加一个新的公司我们的weather data就要重新编译一遍,但是在正常的项目里面,weatherdata往往时是独立的进程,不会动不动就停下重新编译的,所以这个思路的拓展性很不好,所以接下来我们用观察者模式试试。
解决的问题:
1)其他第三方公司接入气象站获取数据的问题
2)在运行时动态添加第三方
方案二:观察者模式
了解观察者模式:
就像定牛奶业务:
1)奶站:Subject
2) 用户:Observer
Subject:登记注册,移除和通知
<interface>Subject
registerObserver()
removeObserver()
notifyObserver()
Observer:接收输入
<interface>Observer
update()
观察者模式:对象之间多对一依赖关系的一种设方案,被依赖的对象Subject ,依赖的对象是Observer,Subject通知Observer的变化
1)WeatherDataSubject
//在原来的类中添加三个方法:登记注册,移除和通知,这里的观察者是公告板
registerObserver()
removeObserver()
notifyObservers()
getTemperature()
getHumidity()
getPressure()
dataChange()
2)CurrentConditionObservers
Updata()
display()
//当公告板有增加或删除时,就会通过Updatable()告诉 WeatherDataSubject去登记注册,或移除
//当WeatherDataSubject 有数据变化的时候,就通过 notifyObservers()告诉CurrentConditionObservers去display();
代码实现:
1)Observer接口:
package com.java.internetweatherObservermode;
public interface Observer {
public void update( float temperature, float pressure,float humidity) ;
}
2)Subject接口:
package com.java.internetweatherObservermode;
public interface Subject {
public void registerObserver(Observer o);
public void remodeObserver(Observer o);
public void notifyObserver();
}
3)当前公告板类
package com.java.internetweatherMode;
import com.java.internetweatherObservermode.Observer;
//实现Observer接口(观察者)
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("****Taday temperature : "+temperature+"****");
System.out.println("****Taday pressure: "+pressure+"****");
System.out.println("****Taday humiduty: "+humidity+"****");
}
}
4)预测天气公告板类
package com.java.internetweatherMode;
import com.java.internetweatherObservermode.Observer;
//另外一个观察者
public class ForcastConditions 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("****Tomorrow temperature : "+(temperature+Math.random())+"****");
System.out.println("****Tomorrow pressure: "+(pressure+10*Math.random())+"****");
System.out.println("****Tomorrow humiduty: "+(humidity+Math.random())+"****");
}
}
5)天气数据类(数据的提供者,
实现Subject接口)
package com.java.internetweatherMode;
import java.util.ArrayList;
import com.java.internetweatherObservermode.Observer;
import com.java.internetweatherObservermode.Subject;
//实现Subject接口
public class WeatherDataSt implements Subject {
private float temperature;
private float humidity;
private float pressure;
//因为我们不知道以后观察者有点多少,所以我们使用ArrayList集合,完成相应的操作
private ArrayList<Observer> observers;
//有了公告板后,我们就可以把它当作一个属性,被接口使用
private CurrentConditions currentConditions;
//在构造函数里将观察者初始化
public WeatherDataSt( ) {
observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void remodeObserver(Observer o) {
if(observers.contains(o))
{
observers.remove(o);
}
}
@Override
public void notifyObserver() {
for(int i = 0 ; i < observers.size(); i++ ) {
observers.get(i).update(getTemperature(), getPressure(), getHumidity());
}
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
public void dataChange() {
//当有新的数据之后,我们就调用 notifyObserver()
notifyObserver() ;
}
//假设气象站有数据变化setData()模拟了气象站,有数据变化并告诉weatherdata有新数据了,然后waetherdata进行数据的更新();
public void setData(float temperature, float pressure,float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
dataChange();
}
}
6)测试类:
package com.java.internetweatherMode;
public class InternerWeather {
public static void main(String[] args) {
WeatherDataSt weatherDataSt = new WeatherDataSt( ) ;
CurrentConditions currentconditions = new CurrentConditions() ;
ForcastConditions forcastconditions = new ForcastConditions();
weatherDataSt.registerObserver(forcastconditions);
weatherDataSt.registerObserver(currentconditions );
weatherDataSt.setData(20, 150, 20);
System.out.println("删除当前公告板的消息后");
//此时就可以在这里直接添加或者删除观察者,而不需要在weatherdatast那操作了。
weatherDataSt.remodeObserver(currentconditions);
weatherDataSt.setData(15, 180, 20);
}
}
output:
****Tomorrow temperature : 20.050391790625735****
****Tomorrow pressure: 154.9485208171542****
****Tomorrow humiduty: 20.820273884785347****
****Taday temperature : 20.0****
****Taday pressure: 150.0****
****Taday humiduty: 20.0****
删除当前公告板的消息后
****Tomorrow temperature : 15.068996039881723****
****Tomorrow pressure: 189.28580553999814****
****Tomorrow humiduty: 20.16418761237121****
观察者模式的定义:
Observer模式是行为模式之一,它的作用是当一个对象的状态反思鞥变化时,能够子自动通知其他关联对象,自动刷新对象的状态。
Observer模式提供给关联对象一种同步通信的手段,使用某个对象与依赖它的其他对象之间保持状态同步。
个人在极客学院的视频学习笔记
网友评论