美文网首页
设计模式(三)观察者模式

设计模式(三)观察者模式

作者: Active_Loser | 来源:发表于2019-03-10 22:43 被阅读0次

    总章目录,设计模式(一)基本介绍

    一、定义

    观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会受到通知并自动更新。
    观察者模式需要理解2个对象,观察者和被观察者:
    举个通用的例子:我们订阅报纸,那订阅报纸的用户则为观察者,二报社则为被观察者,而报社一旦发布新的报纸都会给订阅人发报。


    观察者模式的主要角色如下。
    抽象主题(Subject):也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
    具体主题(Concrete Subject):也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
    抽象观察者(Observer):它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
    具体观察者(Concrete Observer):实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态

    二、代码示例

    自己打造一个观察者模式

    思考下,为实时显示气象站获取的气象信息,我们不采取观察者设计模式,怎么去解决这个问题。


    Subject :

    public interface Subject {
        void addObserver(Observer observer);
    
        void removeObserver(Observer observer);
    
        void notifyObservers();
    
    }
    

    Observer

    public interface Observer {
    
        /**
         * 更新
         */
        void update(float temp, float humidity, float pressure);
    }
    

    Concrete Subject:

    public class WeatherData implements Subject {
    
        List<Observer> observers;
        float temp;
        float humidity;
        float pressure;
    
        public WeatherData() {
            observers = new ArrayList<>();
        }
    
        @Override
        public void addObserver(Observer observer) {
            observers.add(observer);
        }
    
        @Override
        public void removeObserver(Observer observer) {
            observers.remove(observer);
        }
    
        @Override
        public void notifyObservers() {
            for (Observer observer : observers) {
                observer.update(temp, humidity, pressure);
            }
        }
    
        public void setWeather(float temp, float humidity, float pressure) {
            this.temp = temp;
            this.humidity = humidity;
            this.pressure = pressure;
    
            notifyObservers();
        }
    }
    

    Concrete Observer:

    
    public class CurrentConditions implements Observer {
        float temp;
        float humidity;
        float pressure;
    
        @Override
        public void update(float temp, float humidity, float pressure) {
            this.temp = temp;
            this.humidity = humidity;
            this.pressure = pressure;
    
            showWeather();
        }
    
        private void showWeather() {
            System.out.println("this="+this+"temp:" + temp + "humidity:" + humidity + "pressure:" + pressure);
        }
    }
    
    

    测试输出:

    public class ObserverTest {
    
        @Test
        public void ObserverTest(){
            WeatherData weatherData=new WeatherData();
    
            CurrentConditions currentCondition1=new CurrentConditions();
            CurrentConditions currentCondition2=new CurrentConditions();
            weatherData.addObserver(currentCondition1);
            weatherData.addObserver(currentCondition2);
    
            weatherData.setWeather(10,20,30);
            weatherData.setWeather(50,60,70);
    
            weatherData.removeObserver(currentCondition1);
    
            weatherData.setWeather(50,60,80);
        }
    }
    
    打印:
    this=com.active_loser.Observer.CurrentConditions@1da51a35temp:10.0humidity:20.0pressure:30.0
    this=com.active_loser.Observer.CurrentConditions@4b53f538temp:10.0humidity:20.0pressure:30.0
    this=com.active_loser.Observer.CurrentConditions@1da51a35temp:50.0humidity:60.0pressure:70.0
    this=com.active_loser.Observer.CurrentConditions@4b53f538temp:50.0humidity:60.0pressure:70.0
    this=com.active_loser.Observer.CurrentConditions@4b53f538temp:50.0humidity:60.0pressure:80.0
    

    通过上面打印的日志,可以看出,当温度改变后,所有订阅的对象都会受到信息,当某对象取消订阅,将不会收到消息。
    tip:当然我们可以利用系统提供的观察者Observer能够够方便的实现。

    使用系统观察者实现

    通过setChanged()notifyObservers()通知状态改变

    public class WeatherData extends Observable {
    
        private float temp;
        private float humidity;
        private float pressure;
    
        public float getTemp() {
            return temp;
        }
    
        public float getHumidity() {
            return humidity;
        }
    
        public float getPressure() {
            return pressure;
        }
    
        public void setWeatherData(float temp, float humidity, float pressure) {
            this.temp = temp;
            this.humidity = humidity;
            this.pressure = pressure;
            //**标识状态已改表**
            setChanged();
            notifyObservers();
        }
    }
    
    
    public class CurrentConditions implements Observer {
    
        private float temp;
        private float humidity;
        private float pressure;
    
        @Override
        public void update(Observable o, Object arg) {
            WeatherData weatherData = (WeatherData) arg;
            System.out.println("this=" + this + "temp:" + temp + "humidity:" + humidity + "pressure:" + pressure);
        }
    }
    
    

    相关文章

      网友评论

          本文标题:设计模式(三)观察者模式

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