首页 > web前端 > js教程 > JavaScript设计模式:观察者模式

JavaScript设计模式:观察者模式

尊渡假赌尊渡假赌尊渡假赌
发布: 2025-02-16 11:00:15
原创
949 人浏览过

JavaScript Design Patterns: The Observer Pattern

JavaScript观察者模式的关键要点

  • JavaScript中的观察者模式允许元素之间进行一对多的数据绑定,这对于保持多个元素与相同数据同步特别有用。
  • 观察者模式包含三个主要方法:subscribe(添加新的可观察事件)、unsubscribe(移除可观察事件)和broadcast(使用绑定数据执行所有事件)。
  • 使用ES6特性(例如类、箭头函数和常量)可以有效地实现观察者模式,使代码更简洁、更易于重用。
  • 观察者模式可用于解决JavaScript中的实际问题,例如在每次击键时更新博客文章中的字数统计,并可进一步增强以构建新功能。

在JavaScript中,经常会遇到一个问题:需要一种方法来响应某些事件更新页面的一部分,并使用这些事件提供的数据。例如,用户输入,然后将其投影到一个或多个组件中。这会导致代码中出现大量的推拉操作以保持所有内容同步。这就是观察者设计模式可以提供帮助的地方——它实现了元素之间的一对多数据绑定。这种单向数据绑定可以是事件驱动的。使用此模式,您可以构建可重用的代码来解决您的特定需求。在本文中,我想探讨观察者设计模式。它将帮助您解决在客户端脚本中经常遇到的一个常见问题。那就是一对多、单向和事件驱动的绑定。当您有很多必须同步的元素时,这个问题经常出现。我将使用ECMAScript 6来说明这种模式。是的,将会有类、箭头函数和常量。如果您还不熟悉,可以自行探索这些主题。我将只使用ES6中引入语法糖的部分,因此如果需要,它也可以与ES5一起使用。我将使用测试驱动开发(TDD)来处理该模式。这样,您就可以知道每个组件如何使用。ES6中的新语言特性使代码更简洁。那么,让我们开始吧。

事件观察者

该模式的高级视图如下所示:

<code>EventObserver
│ 
├── subscribe: 添加新的可观察事件
│ 
├── unsubscribe: 移除可观察事件
│
└── broadcast: 使用绑定数据执行所有事件</code>
登录后复制
登录后复制
登录后复制

在详细阐述观察者模式之后,我将添加一个使用它的字数统计功能。字数统计组件将使用此观察者并将所有内容整合在一起。要初始化EventObserver,请执行以下操作:

class EventObserver {
  constructor() {
    this.observers = [];
  }
}
登录后复制
登录后复制
登录后复制

从一个空的观察事件列表开始,每个新实例都这样做。从现在开始,让我们在EventObserver中添加更多方法来完善设计模式。

subscribe方法

要添加新事件,请执行以下操作:

subscribe(fn) {
  this.observers.push(fn);
}
登录后复制
登录后复制
登录后复制

获取观察事件列表并将新项目推送到数组中。事件列表是回调函数列表。在纯JavaScript中测试此方法的一种方法如下:

<code>EventObserver
│ 
├── subscribe: 添加新的可观察事件
│ 
├── unsubscribe: 移除可观察事件
│
└── broadcast: 使用绑定数据执行所有事件</code>
登录后复制
登录后复制
登录后复制

我使用Node断言在Node中测试此组件。完全相同的断言也存在于Chai断言中。请注意,观察事件列表由简单的回调组成。然后,我们检查列表的长度并断言回调位于列表中。

unsubscribe方法

要移除事件,请执行以下操作:

class EventObserver {
  constructor() {
    this.observers = [];
  }
}
登录后复制
登录后复制
登录后复制

从列表中过滤掉与回调函数匹配的任何内容。如果没有匹配项,则回调将保留在列表中。过滤器返回一个新列表并重新分配观察者列表。要测试此好方法,请执行以下操作:

subscribe(fn) {
  this.observers.push(fn);
}
登录后复制
登录后复制
登录后复制

回调必须与列表上的相同函数匹配。如果存在匹配项,则unsubscribe方法会将其从列表中移除。请注意,测试使用函数引用来添加和移除它。

broadcast方法

要调用所有事件,请执行以下操作:

// Arrange
const observer = new EventObserver();
const fn = () => {};

// Act
observer.subscribe(fn);

// Assert
assert.strictEqual(observer.observers.length, 1);
登录后复制

这将遍历观察事件列表并执行所有回调。有了这个,您就可以获得与已订阅事件所需的一对多关系。您可以传入data参数,这使得回调数据绑定。ES6使用箭头函数使代码更有效。请注意(subscriber) => subscriber(data)函数执行了大部分工作。此单行箭头函数受益于这种简短的ES6语法。这是JavaScript编程语言的明显改进。要测试此broadcast方法,请执行以下操作:

unsubscribe(fn) {
  this.observers = this.observers.filter((subscriber) => subscriber !== fn);
}
登录后复制

使用let而不是const,以便我们可以更改变量的值。这使得变量可变,允许我在回调中重新分配其值。在代码中使用let向其他程序员发出信号,表明变量在某些时候正在发生变化。这增加了JavaScript代码的可读性和清晰度。此测试使我有足够的信心来确保观察者按预期工作。使用TDD,一切都是关于在纯JavaScript中构建可重用代码。在纯JavaScript中编写可测试代码有很多好处。测试所有内容,并保留对代码重用有益的内容。有了这个,我们已经完善了EventObserver。问题是,您可以用它构建什么?

观察者模式的实际应用:博客字数统计演示

对于演示,是时候创建一个博客文章,让它为您保留字数统计了。您输入的每个击键都将由观察者设计模式同步。将其视为自由文本输入,其中每个事件都会触发更新到您需要它去的地方。要从自由文本输入中获取字数统计,可以执行以下操作:

// Arrange
const observer = new EventObserver();
const fn = () => {};

observer.subscribe(fn);

// Act
observer.unsubscribe(fn);

// Assert
assert.strictEqual(observer.observers.length, 0);
登录后复制

完成了!这个看似简单的纯函数中有很多内容,那么一个简单的单元测试怎么样?这样一来,我的意图就清楚了:

<code>EventObserver
│ 
├── subscribe: 添加新的可观察事件
│ 
├── unsubscribe: 移除可观察事件
│
└── broadcast: 使用绑定数据执行所有事件</code>
登录后复制
登录后复制
登录后复制

请注意blogPost中有点古怪的输入字符串。我的目的是让此函数涵盖尽可能多的边缘情况。只要它能给我一个正确的字数统计,我们就朝着正确的方向前进。顺便说一句,这就是TDD的真正力量。可以迭代此实现并涵盖尽可能多的用例。单元测试告诉您我期望它的行为。如果行为存在缺陷,无论出于何种原因,都很容易迭代和调整它。通过测试,为其他人留下足够的证据来进行更改。是时候将这些可重用组件连接到DOM了。这是您将纯JavaScript掌握并将其焊接到浏览器中的部分。一种方法是在页面上使用以下HTML:

class EventObserver {
  constructor() {
    this.observers = [];
  }
}
登录后复制
登录后复制
登录后复制

然后是以下JavaScript:

subscribe(fn) {
  this.observers.push(fn);
}
登录后复制
登录后复制
登录后复制

获取所有可重用代码并设置观察者设计模式。这将跟踪文本区域中的更改,并在其下方为您提供字数统计。我正在DOM API中使用body.appendChild()来添加此新元素。然后,附加事件侦听器以使其栩栩如生。请注意,使用箭头函数可以连接单行事件。事实上,您可以使用它将事件驱动的更改广播给所有订阅者。() => blogObserver.broadcast()在这里完成了大部分工作。它甚至将文本区域的最新更改直接传递到回调函数中。是的,客户端脚本非常酷。没有一个您可以触摸和调整的演示是完整的,下面是CodePen:(此处应插入CodePen链接,由于无法访问外部网站,无法提供)

现在,我不会称此功能为完整的功能。但这只是观察者设计模式的起点。我心中的问题是,您愿意走多远?

展望未来

您可以进一步发展这个想法。您可以使用观察者设计模式来构建许多新功能。您可以使用以下方法增强演示:

  • 另一个组件计算段落数
  • 另一个组件显示输入文本的预览
  • 使用markdown支持增强预览,例如

这些只是您可以深入研究的一些想法。上述增强功能将挑战您的编程能力。

结论

观察者设计模式可以帮助您解决JavaScript中的实际问题。这解决了保持一堆元素与相同数据同步的长期问题。通常情况下,当浏览器触发特定事件时。我相信你们中的大多数人现在已经遇到了这样的问题,并且已经转向工具和第三方依赖项。此设计模式使您能够走得尽可能远。在编程中,您将解决方案抽象成模式并构建可重用的代码。这将带给您的好处是无限的。我希望您能看到,只需一点纪律和努力,您就可以在纯JavaScript中完成多少工作。该语言中的新特性,例如ES6,可以帮助您编写一些简洁且可重用的代码。

(此处应包含JavaScript观察者模式的常见问题解答,但由于篇幅限制,已省略。)

以上是JavaScript设计模式:观察者模式的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板