资讯专栏INFORMATION COLUMN

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

dockerclub / 1158人阅读

摘要:小丽总是会在朋友圈发布自己的各种生活状态。总结我们从观察者模式特点入手,通过一个案例,一步一步完善了观察着的写法,特点组后介绍了总已有的实现关注我,这里只有干货同系列文章从未这么明白的设计模式一单例模式


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

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

案例

小丽长得很漂亮,"天生丽质难自弃", 是一个不折不扣的"女神"。

小丽身边有很多”备胎“,他们通过各种方式添加了小丽的微信,“小豪,小吴”都是其中之一。

小丽总是会在朋友圈发布自己的各种生活状态。

”备胎们“总是及时并且积极地和女神互动!

小丽发现”备胎“小豪不爱互动了,于是删除了“备胎”小豪的微信。

小豪发现自己看不了女神动态了。最终死心!

小丽认识了新“备胎”小李,于是小李也添加了女神微信。

小丽发布自己的朋友圈动态,小李也开始了互动!

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

代码实现 V1.0

Beauty代表女神,LittleBoy表示备胎,他们时刻在关注着女神的朋友圈,希望获得互动,代码实现如下:

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();
    }
}

运行结果如下:

嗯!似乎很完美! 美中不足的是好像LittleBoy的run方法一直在轮询查看女神朋友圈,它没办法做自己的事情了:

这样下去很快他就会失去和女神互动的耐心! 所以我们稍微修改下,让这段代码看起来更加”智能”。

V2.0

为了不让LittleBoy一直轮询查看女神状态,我们可以修改为女神主动推送她的状态给“备胎们”,这样他们就可以去做其他事情了!

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

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


嗯!这样一来就智能多了! 女神更新朋友圈后主动推送消息给备胎!备胎不用死守着女神的朋友圈,而是收到消息后自动去查看。所以他们的关系是这样了:

但是,现在又有一个新问题!这段代码好像显得不够面向对象,不够专业。

女神如果想要新加一个舔狗,就要动女神的逻辑代码。

新加了一个备胎之后,不知道如何把自己的动态分享给他(例如上面的active方法,可能“新备胎”没有)。

备胎突然舔不动了怎么办了,他不想再收到女神动态了!

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

V3.0

既然要灵活,面向对象。我们这么处理:将女神抽象为一个接口,并且她要能够删除备胎,添加备胎,通知备胎。同时我们将备胎抽象为一个接口,他能够在收到女神通知后及时做出反应!
Beauty:

LittleBoy:

它们分别有一个实现:BeautyImplLittleBoyImpl:

测试代码:

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("哪里有彩虹告诉我。。。");
    }
}


嗯!通过面向接口编程完美的解决了上面的问题,现在女神这个类已经变得非常灵活了,仔细观察,我们已经把我们上面的说的案例完全实现!现在它们的关系是这样的:

扩展

观察者模式这种发布与订阅的思想使用的非常广泛,基本各个框架,思想都能看到它的身影,而jdk中也已经抽象了观察与被观察者:
java.util.Observer表示观察者:

java.util.Obserable表示被观察者(例如上面的女神):

然后美中不足的是,jdk把Observable设计成了一个类,这并不利于扩展! 当然我们仍然可以自己实现接口,就像上面所做的。

总结

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

关注我,这里只有干货!

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74101.html

相关文章

  • 从未这么明白设计模式(一):单例模式

    摘要:一般来说,这种单例实现有两种思路,私有构造器,枚举。而这种方式又分了饱汉式,饿汉式。通过关键字防止指令重排序。什么是单例?为什么要用单例? 一个类被设计出来,就代表它表示具有某种行为(方法),属性(成员变量),而一般情况下,当我们想使用这个类时,会使用new关键字,这时候jvm会帮我们构造一个该类的实例。而我们知道,对于new这个关键字以及该实例,相对而言是比较耗费资源的。所以如果我们能够想...

    NikoManiac 评论0 收藏0
  • php设计模式

    摘要:我们今天也来做一个万能遥控器设计模式适配器模式将一个类的接口转换成客户希望的另外一个接口。今天要介绍的仍然是创建型设计模式的一种建造者模式。设计模式的理论知识固然重要,但 计算机程序的思维逻辑 (54) - 剖析 Collections - 设计模式 上节我们提到,类 Collections 中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了...

    Dionysus_go 评论0 收藏0
  • php设计模式

    摘要:我们今天也来做一个万能遥控器设计模式适配器模式将一个类的接口转换成客户希望的另外一个接口。今天要介绍的仍然是创建型设计模式的一种建造者模式。设计模式的理论知识固然重要,但 计算机程序的思维逻辑 (54) - 剖析 Collections - 设计模式 上节我们提到,类 Collections 中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了...

    vspiders 评论0 收藏0
  • 嗨!这是一篇值得深入学习控件-RecyclerView(源码解析篇)

    摘要:其实通过父类的这个方法之后会调用它的方法,这个名字熟悉自定义的童鞋都知道了。 为什么要写这篇源码解析呢? 我一直在说RecyclerView是一个值得深入学习,甚至可以说是一门具有艺术性的控件。那到底哪里值得我们花时间去深入学习呢。没错了,就是源码的设计。但是看源码其实是一件不简单的事情,就拿RecyclerView的源码来说,打开源码一看,往下拉啊拉啊,我擦,怎么还没到头,汗.......

    myeveryheart 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<