观察者设计模式

17 Mar 2025 | 4 分钟阅读

观察者设计模式是一种行为设计模式,其中对象被表示为观察者,它们等待事件触发。 当触发新事件时,多个观察者会捕获这些事件。

事件源(或对象)附加到主题。 每当主题发生变化时,观察者都会通知它。 它遵循对象之间的一对多方法,以便主题中的一个变化将反映在其所有依赖项中并自动更新。

让我们使用现实世界的例子来理解上述概念。

如果我们是报纸或杂志订阅者,我们不需要去商店获取新闻。 我们在家收到报纸。 如果有新的更新可用,出版商会在发布后立即将其直接发送到我们的邮箱。

出版商掌握了有关订阅者的完整信息。 如果订阅者不感兴趣,可以停止出版商的服务。

未使用观察者设计模式的问题

想象一下,客户对尚未发布的产品(假设是一款新手机)感兴趣。 但是,它很快就会在商店里销售,因此客户可以定期访问商店并查看可用性。 但是这些访问毫无意义,因为该产品仍在途中。

除了这样做,商店可以发送几封电子邮件,但这会打扰那些对新产品不感兴趣的人。

在这里,出现了两个问题:客户要么浪费时间检查产品可用性,要么电子邮件会通过通知错误的客户而烦恼。

使用观察方法解决方案

包含一些有趣信息的对象被表示为主题。 它通知其他对象更改其状态,这被称为发布者。 所有想要跟踪发布者状态变化的其它对象都称为订阅者。

在观察者方法中,发布者类由订阅方法组成,以便每个对象可以订阅和取消订阅该发布者正在发生的事件。 这种机制可能看起来有点难,但实际上并不像听起来那么复杂。 发布者-订阅者机制由以下方法组成。

  • 对订阅者对象的引用列表。
  • 各种公共方法提供了从列表中添加和删除订阅者的功能。

通过观察者方法,每当发布者发生任何事件时,它会直接转移给订阅者,并调用其对象上的确切通知方法。

一个应用程序可能需要多个订阅者类来跟踪来自同一发布者类的事件。 但是发布者无法附加到所有这些订阅者类。

所有订阅者和发布者都会实现一个通用接口,以使用该接口与订阅者通信。 该接口应声明通知方法,并且该方法包含发布者可以用来传递一些数据以及通知的参数集。

我们可以修改接口,使其与所有订阅者兼容,以便与不同类型的发布者一起使用。 我们只需要指定几个订阅方法。

Observer Design Pattern

观察者设计模式的实现

让我们了解以下代码片段。

示例 -

输出

Current Task Downloading
Working_Class running: 1 (1)
Working_Class running: 1 (1)
Working_Class running: 1 (1)
Task CompletedTask CompletedTask Completed
Working_Class running: 2 (5)
Working_Class running: 2 (5)
Working_Class running: 2 (5)
Task Completed
Task Completed
Working_Class running: 3 (5)
Task Completed
Working_Class running: 3 (5)
Working_Class running: 3 (5)
Task CompletedTask Completed

Working_Class running: 4 (5)Working_Class running: 4 (5)Task Completed

Working_Class running: 4 (5)
Task CompletedTask Completed
Working_Class running: 5 (5)

Working_Class running: 5 (5)
Task Completed
Working_Class running: 5 (5)
Task Completed
Task Completed
Task Completed

解释 -

在上面的代码中,我们解释了下载结果的方式,其中每个对象都被视为观察者。

观察者设计模式的优点

以下是观察者设计模式的一些优点。

  • 它非常灵活,可以在运行时设置对象之间的关系。
  • 借助开放/封闭原则,我们可以在不更改发布者代码的情况下引入新的订阅者类。
  • 此方法仔细描述了对象和观察者之间存在的耦合。

观察者设计模式的缺点

以下是观察者设计模式的一些缺点。

  • 观察者方法有实施风险。 如果未仔细实施,它将导致大型复杂代码。
  • 观察者设计模式的主要缺点是订阅者以随机顺序收到通知。
  • 观察者设计模式中也存在内存泄漏问题,这是由于观察者的显式注册和注销造成的。

适用性

  • 如果一个对象的状态有多个依赖项,则应使用观察者方法。 它遵循一对多的依赖关系,这意味着对象状态的任何变化都将反映在附加对象中(在松散耦合的情况下)。
  • 此方法用于发送通知、电子邮件、消息等。 当我们订阅任何特定网站时,我们会通知您该网站上的任何新事件。
  • 对象应紧密耦合。 如果对象中存在松散耦合,则一个状态的更改将反映在另一个对象中。
  • 订阅者列表是动态的,这意味着订阅者可以根据需要加入和退出订阅。

下一个主题Python 反设计模式