由天气预报问题解析观察者模式
sadasd天气预报需求:气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方)。需要设计开放型API,便于其他第三方也能接入气象站获取数据。
sada d普通方案:
ssdada d通过对气象站项目的分析,我们可以初步设计出一个WeatherData类 :
ssd
ssdada dCurrentConditions : (当前的天气情况) 可以理解成是我们气象局的网站
sada dCurrentConditions的代码实现:
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+"***");
}
}
sada dWeatherData代码实现:
public class WeatherData {
private float temperatrue;
private float pressure;
private float humidity;
private CurrentConditions currentConditions;
public WeatherData(CurrentConditions currentConditions) {
this.currentConditions = currentConditions; }
public float getTemperature() {
return temperatrue; }
public float getPressure() {
return pressure; }
public float getHumidity() {
return humidity; }
public void dataChange() {
currentConditions.update(getTemperature(), getPressure(), getHumidity());
}
public void setData(float temperature, float pressure, float humidity) {
this.temperatrue = temperature;
this.pressure = pressure;
this.humidity = humidity;
dataChange();}
}
sada d测试及结果:
public class InternetWeather {
public static void main(String[] args) {
CurrentConditions currentConditions = new CurrentConditions();
WeatherData weatherData = new WeatherData(currentConditions);
weatherData.setData(30, 150, 40);
}
}
------------------------------------------------------------------------------------
结果:
***Today mTemperature: 30.0***
***Today mPressure: 150.0***
***Today mHumidity: 40.0***
sada d问题:其他第三方接入气象站获取数据的问题,无法在运行时动态的添加第三方 (新浪网站),违反了ocp原则,因此我们推出 观察者模式。
观察者模式
sadasd观察者模式类似订牛奶业务,奶站/气象局:Subject。 用户/第三方网站:Observer
sadasdUML图如下:
sadassdsdsdsdsdsdd
sadasdSubject:登记注册、移除和通知
sadasdregisterObserver : 注册
sadasdremoveObserver : 移除
sadasdnotifyObservers() : 通知所有的注册的用户,根据不同需求,可以是更新数据,让用户来取,也可能是实施推送,看具体需求定
sadasd【优点】:观察者模式设计后,会以集合的方式来管理用户(Observer),包括注册,移除和通知,这样,我们增加观察者(这里可以理解成一个新的公告板),就不需要去修改核心类WeatherData不会修改代码,遵守了ocp原则。
sadasd【适用于】:对象之间 多对一 依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化,比如这里的奶站是Subject,是1的一方。用户时Observer,是多的一方。
sada dSubject接口 :
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
sada dObserver接口 :
public interface Observer {
public void update(float temperatrue,float pressure,float humidity);
}
sada dObserver接口的子类(不同网站):
public class CurrentConditions implements Observer{
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 BaiSite implements Observer {
private float temperature;
private float pressure;
private float humidity;
@Override
public void update(float temperatrue, float pressure, float humidity) {
this.temperature=temperature;
this.pressure=pressure;
this.humidity=humidity;
display();
}
public void display(){
System.out.println("***百度网站 气温: "+temperature+"***");
System.out.println("***百度网站 气压: "+pressure+"***");
System.out.println("***百度网站 湿度: "+humidity+"***");
}
}
sada dSubject接口子类:
public class WeatherData implements Subject {
private float temperatrue;
private float pressure;
private float humidity;
private List<Observer> observers;
public WeatherData( ) {
observers = new ArrayList<Observer>();
}
public float getTemperature() {
return temperatrue; }
public float getPressure() {
return pressure; }
public float getHumidity() {
return humidity; }
public void dataChange() {
notifyObservers();
}
public void setData(float temperature, float pressure, float humidity) {
this.temperatrue = temperature;
this.pressure = pressure;
this.humidity = humidity;
dataChange();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
if(observers.contains(o)){
observers.remove(o);
}
}
@Override
public void notifyObservers() {
for(int i=0 ; i<observers.size() ; i++){
observers.get(i).update(this.temperatrue,this.pressure,this.humidity);
}
}
}
sada d测试及结果:
public class InternetWeather {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
weatherData.registerObserver(new CurrentConditions());
weatherData.registerObserver(new BaiSite());
weatherData.setData(30, 150, 40);
}
}
***Today mTemperature: 30.0***
***Today mPressure: 150.0***
***Today mHumidity: 40.0***
***百度网站 气温: 0.0***
***百度网站 气压: 150.0***
***百度网站 湿度: 40.0***
sadasd观察者的好处:以集合的形式来管理用户,包括注册,移除和通知。这样我们增加观察者,就不需要去修改核心类WeatherData,遵守了ocp原则。