美文网首页
设计模式之观察者模式

设计模式之观察者模式

作者: 零星瓢虫 | 来源:发表于2020-05-05 12:59 被阅读0次

前言

观察者模式,即为观察对象的变化,并能够随时得到对象变化的通知。此类模式我们在平时开发中所见的也比较多,例如我们安卓开发中的Rxjava、EventBus等;

观察者模式

前言中说了。观察者模式即为观察对象的变化,并能够及时得到通知;接下来我们就引入一个例子进行循序渐进地进行分析一下。

现在假如我们手上有个某米的智能设备,此智能设备有个显示屏,同时装备有温度、湿度、气压感应装置。使得显示屏可以显示温度、湿度、气压的情况。

零星瓢虫.png

这里我们就需要显示被通过去观察智能设备的Weather对象,从而当Weather对象只要一变化,相应显示屏就应该去变化。

于是我们想到一种可以去实现的方式:

public class WeatherData {
    public float getTemperature(){
        return 0;
    };
    public float getHumidity(){
        return 0;
        
    };
    public float getPressure(){
        return 0;
        
    };
    
    public void measureChanged(){
        float tem = getTemperature();
        float hum = getHumidity();
        float pre = getPressure();
        
        //显示器显示
        tmpDisPlay.show(tem);
        humDisPlay.show(hum);
        preDisPlay.show(pre);
        
    }
    


我们可以看到这里通过WeatherData类的measureChanged方法对应去显示屏显示;
这样的做法也是能够实现,但是我们设计模式中有一个原则是:针对经常改变的地方,我们应该需要封装起来。而这里,温度,湿度,压力显然是会经常改变的,所有我们应该给封装起来;这里的这些智能检测到的气象数据显然是被观察者,而相应的温度、湿度、气压的显示屏显示则是观察者。在对整个设计进行更改之前我们先来看看观察者模式的类图:

零星瓢虫_001.png

这里我们的WeatherData相当于被观察者,而显示器则相当于观察者需要进行同步数据的显示:

public class WeatherData implements Subject {
    
    private ArrayList <Observer> observers;
    private float tem;
    private float hum;
    private float pre;
    
    public WeatherData(){
        observers = new ArrayList<Observer>();
    }
    
    public void registerObserver(Observer o){
        observers.add(o);
    }

    public void removeObserver(Observer o){
        int i = observers.indexOf(o);
        if(i >= 0){
            observers.remove(i);
        }
    }

    public void notifyObserver(){
        for(Observer o : observers){
            o.update(tem,hum,pre);
        }
    } 
    
    public void measureChanged(){
        notifyObserver();
    }

    public void setMeasureChangeData(float tem, float hum, float pre){
        this.tem = tem;
        this.hum = hum;
        this.pre = pre;
        measureChanged();
    }

}

public class Display implements Observer{
    private float tem;
    private float hum;
    private float pre;
    public WeatherData weatherData;
    
    public Display(Subject weatherData){
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }
    
    public void update( float tem, float hum, float pre){
        this.tem = tem;
        this.hum = hum;
        this.pre = pre;
        display();
    }
    
    public void display(){
        System.out.print("tem="+tem+",hum="+hum+",pre="+pre);
    }

}

这里我们就实现了针对此智能设备观察者和被观察者的设计,目前这里只有一个观察者Display,我们先来使用下这个智能设备。



    public static void main(String [] args){
        WeatherData weatherData = new WeatherData();
        Display display = new Display(weatherData);
        weatherData.setMeasureChangeData(1.0,2.0,3.0);      
    }

当weatherData数据变声了变化,则对应控制台则会打印出"tem=1.0,hum=2.0,pre=3.0,从而及时通知到了Display进行显示相关状态;

这里我们只有一个观察者Display,加入我们这个智能设置还有一个观察者HumDisplay;我们至于要根据湿度的情况来决定是否需要加湿器开启;


public class HumDisplay implements Observer{
    private float tem;
    private float hum;
    private float pre;
    public WeatherData weatherData;
    
    public HumDisplay(Subject weatherData){
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }
    
    public void update( float tem, float hum, float pre){
        this.tem = tem;
        this.hum = hum;
        this.pre = pre;
        display();
    }
    
    public void display(){
        if(hum < 5.0 && hum > 0){
            System.out.print("开启加湿器");
        }
    }

}
public static void main(String [] args){
        WeatherData weatherData = new WeatherData();
        
        Display display = new Display(weatherData);
        HumDisplay humDisplay = new HumDisplay(weatherData);        
        weatherData.setMeasureChangeData(1.0,2.0,3.0);
        
    }

此时我们同样对humDisplay 进行了监听,当检测到weatherData的数据发生了变化,在控制台可以看到打印出“开启加湿器的信号”;

最后我们再看下整个观察者模式中使用到的类以及他们之间的联系:


零星瓢虫_002.png

相关文章

网友评论

      本文标题:设计模式之观察者模式

      本文链接:https://www.haomeiwen.com/subject/jspeghtx.html