解锁设计模式:一文吃透观察者模式

目录

一、什么是观察者模式

二、观察者模式的组成

2.1 主题(Subject)

2.2 具体主题(Concrete Subject)

2.3 观察者(Observer)

2.4 具体观察者(Concrete Observer)

三、观察者模式工作流程

3.1 注册观察者

3.2 状态改变

3.3 通知观察者

3.4 观察者更新

四、观察者模式代码示例

4.1 Java 示例

4.2 JavaScript 示例

五、观察者模式的优缺点

5.1 优点

5.2 缺点

六、观察者模式的应用场景

6.1 事件处理系统

6.2 数据绑定与 MVVM 模式

6.3 消息队列与发布 - 订阅系统

七、总结


一、什么是观察者模式

        观察者模式(Observer Pattern),是一种行为型设计模式,也被称为发布 - 订阅模式(Publish-Subscribe Pattern) 。这种模式定义了对象之间的一种一对多依赖关系,使得每当一个对象(被观察者)的状态发生改变时,其所有依赖于它的对象(观察者)都会得到通知并被自动更新。

        打个比方,就拿我们日常使用的公众号来说。当你关注了一个公众号,这个公众号就相当于被观察者,而你以及其他关注这个公众号的粉丝们就是观察者。一旦公众号发布了新文章(也就是状态发生改变),平台就会自动通知到所有关注它的粉丝(所有观察者收到通知并更新,比如在各自的微信端收到推送消息)。再比如,在股票交易系统中,每只股票就是被观察者,而股民们就是观察者。当某只股票的价格发生变化时,关注这只股票的股民就会收到通知,进而可以根据价格变化做出相应的决策。

二、观察者模式的组成

        观察者模式主要包含四个核心角色:主题(Subject)、具体主题(Concrete Subject)、观察者(Observer)和具体观察者(Concrete Observer)。下面我将为大家一一介绍。

2.1 主题(Subject)

        主题也被称为抽象目标类,它是一个接口或者抽象类 ,定义了一系列管理观察者的方法,是整个观察者模式的核心纽带。其主要作用是提供一个统一的管理观察者的接口,使得具体主题类可以方便地添加、删除和通知观察者。在主题接口或抽象类中,通常会包含以下方法:

  • 注册观察者方法:用于将观察者对象添加到主题的观察者列表中,使主题能够知道有哪些观察者对它的状态变化感兴趣。比如在前面提到的公众号例子中,公众号提供的 “关注” 功能就相当于注册观察者的方法,用户通过关注公众号,将自己注册为观察者。

  • 注销观察者方法:与注册方法相反,用于将不再感兴趣的观察者从观察者列表中移除。例如公众号的 “取消关注” 功能,用户取消关注公众号,就相当于从公众号的观察者列表中注销自己。

  • 通知观察者方法:当主题的状态发生变化时,调用此方法通知所有注册的观察者,告知它们主题状态已改变,以便观察者做出相应的处理。如公众号发布新文章后,会通过通知方法向所有关注它的用户发送推送通知。

2.2 具体主题(Concrete Subject)

        具体主题类是主题接口的具体实现,它负责维护一个观察者列表,存储所有对其感兴趣的观察者对象 。当具体主题的内部状态发生改变时,它会遍历观察者列表,调用每个观察者的更新方法,通知它们状态已改变。

        以股票交易系统为例,某只股票就是一个具体主题。它会维护一个包含所有关注这只股票股民(观察者)的列表。当股票价格发生变化时(状态改变),股票这个具体主题就会通知列表中的所有股民,告知他们股票价格的变动情况,股民们(观察者)则可以根据这个通知做出买卖股票的决策。在具体实现中,具体主题类通常会在其内部定义一个用于存储观察者对象的集合,比如 Java 中的ArrayList,然后实现主题接口中定义的注册、注销和通知观察者的方法。

2.3 观察者(Observer)

        观察者是一个接口或者抽象类,它为所有具体观察者定义了一个统一的更新接口 。这个接口的主要作用是让具体观察者实现一个方法,当它们接收到主题的通知时,能够执行相应的操作来更新自身的状态,以与主题的状态保持同步。在观察者接口或抽象类中,一般只定义一个核心的更新方法,这个方法通常会接收主题传递过来的一些状态信息,以便观察者根据这些信息进行自身状态的更新。

        例如在一个游戏场景中,玩家角色是观察者,游戏中的各种事件(如怪物出现、道具刷新等)是主题。玩家角色实现了观察者接口,当怪物出现这个主题发生状态变化(怪物出现了)时,玩家角色作为观察者,会通过实现的更新方法来做出反应,比如准备战斗、调整策略等。

2.4 具体观察者(Concrete Observer)

        具体观察者类实现了观察者接口,它是真正对主题状态变化感兴趣并做出具体响应的对象 。每个具体观察者都有自己独特的业务逻辑,当接收到主题的通知时,它们会根据自身的需求和逻辑,利用主题传递过来的信息来更新自己的状态或者执行特定的操作,从而与主题的状态保持一致。

        继续以上述游戏场景为例,游戏中的不同玩家就是具体观察者。当怪物出现的通知传来时,战士玩家可能会选择直接冲上去攻击怪物;法师玩家则可能会开始吟唱法术,准备远程攻击;而辅助玩家可能会给队友施加增益状态,以提高团队的战斗力。这些不同的玩家(具体观察者)根据自己的角色特点和游戏策略,对怪物出现(主题状态变化)做出了不同的响应,实现了各自独特的业务逻辑。

三、观察者模式工作流程

        了解了观察者模式的组成部分后,接下来我们深入探讨一下它的工作流程,看看各个角色在其中是如何协同工作的。

3.1 注册观察者

        当观察者对主题的状态变化感兴趣时,它会调用主题提供的注册方法,将自己添加到主题的观察者列表中 。这个过程就好比我们在电商平台上关注了某个商品,我们(观察者)通过点击 “关注” 按钮(调用注册方法),将自己的信息(观察者对象)添加到该商品(主题)的关注列表中。在代码实现上,以 Java 语言为例,假设我们有一个Subject接口和一个ConcreteSubject类,以及一个Observer接口和一个ConcreteObserver类:

// 主题接口

interface Subject {

void registerObserver(Observer observer);

void removeObserver(Observer observe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大雨淅淅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值