0
点赞
收藏
分享

微信扫一扫

【设计模式--->行为型模式】叩心自问:观察者模式

慕容冲_a4b8 2022-01-12 阅读 51


由天气预报问题解析观察者模式

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原则。

举报

相关推荐

0 条评论