首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >设计模式16之观察者模式

设计模式16之观察者模式

作者头像
Lvshen
发布2022-05-05 18:21:17
发布2022-05-05 18:21:17
3640
举报

背景

观察者模式你肯定知道并且用过,如果你没听过观察者模式这几个词,那发布-订阅模型你肯定知道。我们在使用Kafka等消息中间件时,就用到了发布-订阅模式进行数据的生产消费。你可以将发布-订阅模式理解为观察者模式。

如下代码:

kafka发布消息:

代码语言:javascript
复制
 ListenableFuture future = kafkaTemplate.send(topic, jsonString);

消费者订阅消息:

代码语言:javascript
复制
@KafkaListener(topics = "${spring.kafka.topic}")
 public void listen(ConsumerRecord<?, ?> record) {
        log.info("topic={}, offset={}, message={}", record.topic(), record.offset(), record.value());
 }

上面就是kafka发布-订阅的使用方法。

除了消息中间件的发布-订阅,zookeeper的watch机制也使用到了观察者模式。各位可以思考下,你在什么情况下会使用观察者模式呢?

什么是观察者模式

在现实生活中,许多对象都不是独立存在的,其中一个对象的改变往往会导致其它对象的改变。比如:到了下班时间你会下班回家,路上遇到红灯你会停下来,股市行情好了你会追加投资。

如果你在开发中要描述上述的关联关系,就可以使用观察者模式。

“Define a one-to-many dependency between objects so that when one object changes state,all its dependents are notified and updated automatically.(定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。) ”

观察者模式的主要由4个要素组成:

  • 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
  • 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
  • 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
  • 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。

结构图如下:

观察者模式

代码实现

Subject

Observer

ConcreteSubject

ConcreteObserver

测试代码如下:

代码语言:javascript
复制
@Test
public void test() {
    Subject subject=new ConcreteSubject();
    Observer obs1=new ConcreteObserver1();
    Observer obs2=new ConcreteObserver2();
    subject.add(obs1);
    subject.add(obs2);
    subject.notifyObserver();
}

测试结果如下:

代码语言:javascript
复制
具体目标发生改变...
--------------
具体观察者1作出反应!
具体观察者2作出反应!

关于观察者模式的思考

我们什么情况下可以使用观察者模式呢?

如果对象之间存在一对多关系,一个对象的状态发生改变会影响其他对象,我们就能使用观察者模式。我举个例子,如果某个商品出现质量问题。我们需要对已经购买该商品的订单冻结,那么我们就可以使用观察者模式。我们对该商品执行冻结命令,冻结该商品的同时,所有包含该商品的订单都会被通知并冻结。

我们再思考一下,在另一个场景中。用户下单后,需要送积分,生成物流信息,短信通知,微信通知,是不是可以使用观察者模式呢?关于这个问题我之前还写了一篇文章探讨使用观察者模式的好处,有兴趣的可以看看。

不知你发现了没有,观察者和被观察者之间的耦合度很低。这样观察者和被观察者很容易扩展。

观察者模式很容易实现一条触发链。什么是触发链呢?比如早上闹钟把你闹醒,你就起床,你肚子饿了,你就会去吃早餐,快到上班时间了,你就会开车去上班,上班时间到了,你就打开电脑开始摸鱼。这一连串的的触发机制就形成了一个触发链。

观察者模式需要考虑一下开发效率和运行效率问题,一个被观察者,多个观察者,开发和调试就会比较复杂,而且在Java中消息的通知默认是顺序执行,一个观察者卡壳,会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Lvshen的技术小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 什么是观察者模式
  • 代码实现
    • Subject
    • Observer
    • ConcreteSubject
    • ConcreteObserver
  • 关于观察者模式的思考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档