从未这么明白的设计模式(二):观察者模式

cover
<!-- more -->java

本文原创地址, 个人博客https://jsbintask.cn/2019/04/15/designpattern/observer/(食用效果最佳),转载请注明出处!

前言

观察者模式定义了对象间的一种一对多依赖关系,当一个对象状态发生改变时,观察者们均可以作出相应的更新,使得系统更易于扩展!
代码地址:https://github.com/jsbintask22/design-pattern-learninggit

案例

  1. 小丽长得很漂亮,"天生丽质难自弃", 是一个彻彻底底的"女神"。
  2. 小丽身边有不少”备胎“,他们经过各类方式添加了小丽的微信,“小豪,小吴”都是其中之一。
  3. 小丽老是会在朋友圈发布本身的各类生活状态。
  4. ”备胎们“老是及时而且积极地和女神互动!
  5. 小丽发现”备胎“小豪不爱互动了,因而删除了“备胎”小豪的微信。
  6. 小豪发现本身看不了女神动态了。最终死心!
  7. 小丽认识了新“备胎”小李,因而小李也添加了女神微信。
  8. 小丽发布本身的朋友圈动态,小李也开始了互动!

上面这个过程咱们能够抽象出来两个主题,女神小丽,备胎小豪,小吴,小李,咱们用代码模拟这个追女神的过程。github

代码实现

V1.0

Beauty表明女神,LittleBoy表示备胎,他们时刻在关注着女神的朋友圈,但愿得到互动,代码实现以下:
Observer
Observer编程

public class App {
    public static void main(String[] args) throws Exception{
        Beauty beauty = new Beauty();
        // 成功添加了女神微信
        LittleBoy littleBoy = new LittleBoy(beauty);

        // 开始查看女神朋友圈
        littleBoy.start();

        // 5s后,女神发布了朋友圈。
        Thread.sleep(5000L);
        beauty.publishWechat();

        System.in.read();
    }
}

运行结果以下:
Observer
嗯!彷佛很完美! 美中不足的是好像LittleBoy的run方法一直在轮询查看女神朋友圈,它没办法作本身的事情了:
Observer
这样下去很快他就会失去和女神互动的耐心! 因此咱们稍微修改下,让这段代码看起来更加”智能”。设计模式

V2.0

为了避免让LittleBoy一直轮询查看女神状态,咱们能够修改成女神主动推送她的状态给“备胎们”,这样他们就能够去作其余事情了!
Observer
Observer微信

public class App {
    public static void main(String[] args) throws Exception{
        Beauty beauty = new Beauty();
        LittleBoy littleBoy = new LittleBoy();
        // 添加女神微信
        beauty.littleBoy = littleBoy;

        // 发布动态
        beauty.publishWechat();
    }
}

Observer
嗯!这样一来就智能多了! 女神更新朋友圈后主动推送消息给备胎!备胎不用死守着女神的朋友圈,而是收到消息后自动去查看。因此他们的关系是这样了:
Observer
可是,如今又有一个新问题!这段代码好像显得不够面向对象,不够专业。框架

  1. 女神若是想要新加一个舔狗,就要动女神的逻辑代码。
  2. 新加了一个备胎以后,不知道如何把本身的动态分享给他(例如上面的active方法,可能“新备胎”没有)。
  3. 备胎忽然舔不动了怎么办了,他不想再收到女神动态了!

既然这样,咱们把这段代码修改下,让它变得“灵活”,更加“面向对象”些!测试

V3.0

既然要灵活,面向对象。咱们这么处理:将女神抽象为一个接口,而且她要可以删除备胎,添加备胎,通知备胎。同时咱们将备胎抽象为一个接口,他可以在收到女神通知后及时作出反应!
Beauty:
Observer
LittleBoy:
Observer
它们分别有一个实现:BeautyImplLittleBoyImpl:
Observer
测试代码:spa

public class App {
    public static void main(String[] args) {
        Beauty beauty = new BeautyImpl();
        LittleBoy boy1 = new LittleBoyImpl("小豪");
        LittleBoy boy2 = new LittleBoyImpl("小吴");

        // 添加两个备胎
        beauty.addLittleBoy(boy1);
        beauty.addLittleBoy(boy2);

        // 发布朋友圈
        beauty.publishWechat("最美的不是下雨天,是曾和你一块儿躲过雨的屋檐!");

        // 删除备胎1,而且新添加了备胎3
        beauty.removeLittleBoy(boy1);
        beauty.addLittleBoy(msg -> {
            System.out.println(" 小李:哎哟,不错哦!");
        });

        // 再次发布朋友圈
        beauty.publishWechat("哪里有彩虹告诉我。。。");
    }
}

Observer
嗯!经过面向接口编程完美的解决了上面的问题,如今女神这个类已经变得很是灵活了,仔细观察,咱们已经把咱们上面的说的案例彻底实现!如今它们的关系是这样的:
Observer设计

扩展

观察者模式这种发布与订阅的思想使用的很是普遍,基本各个框架,思想都能看到它的身影,而jdk中也已经抽象了观察与被观察者:
java.util.Observer表示观察者:
Observer
java.util.Obserable表示被观察者(例如上面的女神):
Observer
而后美中不足的是,jdk把Observable设计成了一个类,这并不利于扩展! 固然咱们仍然能够本身实现接口,就像上面所作的。

总结

咱们从观察者模式特色入手,经过一个案例,一步一步完善了观察着的写法,特色!组后介绍了jdk总已有的实现!

关注我,这里只有干货!

同系列文章:
从未这么明白的设计模式(一):单例模式

相关文章
相关标签/搜索