设计模式&数据结构@IT·互联网程序员

从天气预报说观察者模式

2017-02-26  本文已影响95人  Android开发哥

什么是观察者模式

观察者模式其实在我们生活中特别常见。就像你和隔壁老王订阅了天气和杂志。当有新的信息更新时,你和隔壁老王都会接到通知。
高大上的说法就是基于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;
    }
}

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

调用

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了

什么时候用观察者

上一篇下一篇

猜你喜欢

热点阅读