从天气预报说观察者模式

什么是观察者模式

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

什么时候用观察者

  • 有两个实体类,一个的数据依赖另一个,你想让他们数据能够同步,但是又要相互独立,那就让他们成为观察者把。
  • 当一个变化需要通知其他对象,,那就让他们成为观察者把。
  • 当一个变化需要通知无法推断的对象,那就让他们成为观察者把。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容