从天气预报说观察者模式

作者: Android开发哥 | 来源:发表于2017-02-26 14:39 被阅读95次

    什么是观察者模式

    观察者模式其实在我们生活中特别常见。就像你和隔壁老王订阅了天气和杂志。当有新的信息更新时,你和隔壁老王都会接到通知。
    高大上的说法就是基于Subject这个概念,Subject是一个特殊对象,就是类似上面的天气信息,是作为被观察的事物,称为被观察者。而订阅的Observers,也就是你和老王,的称为观察者。当Subject保存的一系列信息被更新修改后就会通知所有定于的Observers
    比较重要的一点是,观察者之间是没什么关系的,他们可以属于各种各样的人群。
    下面这图看不懂就先算了吧。。。回头再看

    观察者与被观察者

    用Java动手写个观察者Demo呗

    这里找一个场景。例如煎饼是在气象局工作。而煎饼的妈妈和女朋友(假装有女朋友)都订阅了煎饼的明天天气预报信息。到了等到煎饼第一时间知道天气信息更新的时候,就去通知她们两。

    Observer模板

    public interface IObserver<T> {
        void update(T data);
    }
    

    而Observer模板使用接口,是因为上面说到订阅者可以使各种人群,所以他们只需要是实现Observer接口就可以了,而且Java是单继承的。不用接口的话下面就不能去继承了。。。

    Observable模板

    public class Observable<T> {
        private T                   data;
                                    
        private List<IObserver<T>>  observerList    = new ArrayList<>();
                                                    
        private final void attach(IObserver<T> observer) {
            this.observerList.add(observer);
        }
        
        private final void detach(IObserver<T> observer) {
            this.observerList.remove(observer);
        }
        
        public T getData() {
            return data;
        }
        
        public void setData(T data) {
            this.data = data;
            notifyDataChange();
        }
        
        private final void notifyDataChange() {
            for (IObserver<T> observer : observerList) {
                observer.update(data);
            }
        }
    }
    

    这里的Observable模板使用抽象类,因为当信息更新的时候。提醒的行为是不一样的。所以就让实现类去完成这工作。

    Girl实现类

    public class Girl implements IObserver<String> {
        
        private String  name;
        private String  something;
                        
        public Girl() {
        
        }
        
        public Girl(String name, String something) {
            this.name = name;
            this.something = something;
        }
        
        @Override
        public void update(String data) {
            System.out.println(data + ",你要和" + name + something + "。");
        }
        
        public String getName() {
            return name;
        }
        
        public void setName(String name) {
            this.name = name;
        }
        
        public String getSomething() {
            return something;
        }
        
        public void setSomething(String something) {
            this.something = something;
        }
    }
    

    上面就是妈妈和女朋友的观察者实现类,因为逻辑比较简单。所以并没有体现出观察者来自不同的类

    • something : 就是不同的观察者天气改变做出的响应

    调用

    public static void main(String[] args) {
            IObserver<String> mother = new Girl("妈妈", "购物");
            IObserver<String> girlFriend = new Girl("女朋友", "约会");
            Observable<String> jb = new Observable<>();
            jb.attach(mother);
            jb.attach(girlFriend);
            jb.setData("今天天气晴朗,万里晴空");
        }
    

    结果

    今天天气晴朗,万里晴空,你要和妈妈购物。
    今天天气晴朗,万里晴空,你要和女朋友约会。
    

    观察者在Java

    上面是自己写的一个观察者Demo。其实Java里面早就给我们封装好了观察者和被观察者啊哈哈。。。我们看看吧。
    注意一下导包,都是在java.util下面的,别乱导。。。

    Girl2(Observer)

    public class Girl2 implements Observer {
        
        private String  name;
        private String  something;
                        
        public Girl2() {
        
        }
        
        public Girl2(String name, String something) {
            this.name = name;
            this.something = something;
        }
        
        @Override
        public void update(Observable o, Object arg) {
            System.out.println(arg + ",你要和" + name + something + "。");
        }
    }
    

    JBWeather(Observable)

    public class JBWeather extends Observable {
        private String weather;
        
        public String getWeather() {
            return weather;
        }
        
        public void setWeather(String weather) {
            this.weather = weather;
            setChanged();
            notifyObservers(weather);
        }   
    }
    

    调用

    public static void main(String[] args) {
            Observer mother = new Girl2("妈妈", "购物");
            Observer girlFriend = new Girl2("女朋友", "约会");
            JBWeather jb = new JBWeather();
            jb.addObserver(mother);
            jb.addObserver(girlFriend);
            jb.setWeather("今天天气晴朗,万里晴空");
        }
    

    其实观察者模式中有两种推送数据的方法,一种是直接把需要的数据传给订阅者,一个是把自己送出去。。。其中Observable中的notifyObservers()notifyObservers(Object obj)就是这个区别。给参数就只穿数据,不给参数就把自己传出去。我们也可以看到Observer中的参数也是有两个的。。
    还有就是更新信息别忘了setChanged方法,我就是忘了这个,然后就找了很久,最后看了一下源码。。。gg了

    什么时候用观察者

    • 有两个实体类,一个的数据依赖另一个,你想让他们数据能够同步,但是又要相互独立,那就让他们成为观察者把。
    • 当一个变化需要通知其他对象,,那就让他们成为观察者把。
    • 当一个变化需要通知无法推断的对象,那就让他们成为观察者把。

    相关文章

      网友评论

        本文标题:从天气预报说观察者模式

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