前端实践选题-前端框架中的观察者模式 | 豆包MarsCode AI刷题

51 阅读6分钟

设计模式

设计模式是在软件工程中解决常见问题的经典解决方案。它们是一套被反复使用、多数人知晓、经过分类编目的代码设计经验的总结。设计模式可以帮助程序员提高代码的可重用性、可维护性和可扩展性,进而提高大型软件的开发效率。 简单来说,设计模式可以分为以下几类:

  1. 创建型模式:这类模式主要关注对象的创建过程,包括单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式等。
  2. 结构型模式:这类模式主要关注类和对象之间的组合,包括适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式等。
  3. 行为型模式:这类模式主要关注对象之间的通信,包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、状态模式、中介者模式、备忘录模式、访问者模式等。

前端常见的设计模式有单例模式、观察者模式、装饰器模式等。

  • 单例模式确保一个类只有一个实例,并提供一个全局访问点。
  • 装饰器模式动态地给一个对象添加一些额外的职责。
  • 观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。

观察者模式

观察者设计模式是一种行为型设计模式,定义了对象间的一种一对多的依赖关系,其中一个对象(称为Subject)维护着一系列依赖它的对象(称为Observer),并在状态发生变化时通知这些观察者,所有依赖于它的对象(观察者)通常会被调用它们的某个如update的方法得到通知并自动更新。这种模式通常用于实现分布式事件处理系统,在该系统中,当一个对象(Subject)的状态发生变化时,所有依赖它的对象(Observer)会自动收到通知,接着观察者一般会采取相应动作。

结构

  • 主题(Subject) :被观察的对象,维护观察者的列表。
  • 观察者(Observers) :观察主题状态变化并作出响应的对象。
  • 具体主题(ConcreteSubject) :具体实现了主题接口的类。
  • 具体观察者(ConcreteObserver) :具体实现了观察者接口的类,响应主题的变化。

模式涉及的一般接口

  • addObserver(observer) 方法添加观察者,
  • notifyObservers()* 方法通知所有观察者状态更新,
  • setState(state) 方法改变状态并触发通知。

React中的观察者模式

在现代的 JavaScript 框架(如 React、Vue.js 或 Angular)中,观察者模式通常用于状态管理和组件的响应式更新。例如,在 React 中:

  • 状态(State)在 React 组件中充当 Subject
  • 依赖于状态的组件(即根据状态渲染 UI 的组件)充当 Observer
  • 当状态发生变化时(通过用户输入或外部事件触发),React 会自动重新渲染受影响的组件。

parent component

import React, { useState } from 'react';
import Counter from './Counter';

function App() {
  // Create a piece of state to store the counter value
  const [count, setCount] = useState(0);

  // Function to increment the counter
  const increment = () => {
    setCount(count + 1); // Update state, which triggers a re-render
  };

  return (
    <div>
      <h1>React State Example</h1>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      {/* Pass the current count to the Counter component as a prop */}
      <Counter count={count} />
    </div>
  );
}

export default App;

child component

import React from 'react';

function Counter({ count }) {
  return (
    <div>
      <h2>Counter Component</h2>
      <p>The current count is: {count}</p>
    </div>
  );
}

export default Counter;

观察者模式的优缺点

优点

  1. 解耦:观察者模式最重要的优点就是将主题和观察者的通信过程解耦。主题不需要知道观察者的具体实现,只需要知道它们实现了 update 方法,并将自己被观察的状态完全传入给update函数。这使得代码更加简洁和模块化。
  2. 动态关系:观察者可以在运行时动态地添加或移除。这使得系统更加灵活,便于扩展和调整。
  3. 自动更新:当主题的状态变化时,所有观察者都会自动得到通知并更新,无需手动跟踪状态变化。
  4. 促进复用:相同的观察者可以在多个不同的主题之间复用,从而提高了组件的可重用性。

缺点

  1. 内存泄漏:如果观察者没有正确移除,可能会导致内存泄漏,尤其是在长时间运行的应用程序或单页面应用(SPA)中。问题发生在当观察者对象的引用没有被清除时。
  2. 性能开销:当观察者的数量非常多时,每次主题状态变化时通知所有观察者会增加性能开销,可能导致性能下降。
  3. 不可预测的行为:如果多个观察者依赖同一个主题,并且执行复杂的操作,它们之间的交互可能导致不可预测或不一致的行为,尤其是在异步环境下。
  4. 复杂性:如果没有仔细实现,观察者模式可能会增加系统的复杂性。尤其是在有大量观察者的系统中,跟踪状态变化及其对多个组件的影响可能变得非常困难。

Web开发中的其它使用场景

  • 实时更新:观察者模式非常适合实时应用程序,例如股票行情、聊天应用或协同文档编辑。
  • 事件处理:像 React、Angular 和 Vue.js 这样的框架内部使用观察者模式的变种来保持 UI 与应用程序状态同步。
  • 表单验证:可以通过观察者模式监听表单输入的变化,每当用户输入时,观察者(验证器)会检查输入的有效性。
  • WebSocket客户端:WebSocket连接可以充当主题,通知观察者关于实时消息的更新。例如,在聊天应用中,多个 UI 部件会随着新消息的到来而自动更新。

结论

观察者模式在 Web 开发中应用广泛,特别适用于动态的、事件驱动的应用程序。它能够帮助简化复杂的系统,通过解耦组件实现模块化,但在处理大量观察者时,需要特别注意内存管理和性能优化。现代框架如 React 就利用了类似的概念来管理组件状态和响应式更新。