前端实践选题:浅谈前端框架中的设计模式(二) | 青训营

48 阅读6分钟

前言

在计算机专业的学习中,掌握知识点是至关重要的。然而,仅仅听课和阅读教材可能并不足以真正理解和应用所学的内容。在这个信息爆炸的时代,我们需要更加主动和高效地学习,以提升自己在计算机领域的竞争力。而实践记录和笔记,作为学习的得力助手,能够帮助我们更好地理解知识点,加深记忆,并提供一个有组织的学习框架。我们可以不断总结和反思,发现自己的不足之处,并逐步提升自己的学习能力和解决问题的能力~让我们一起开启笔记/实践记录的学习之旅吧!

image.png

浅谈前端框架中的设计模式

今天我们来学习和记录一下前端性能优化与调试技巧的实战内容,这篇文章记录学习的是前端框架中的设计模式的实际例子内容。

前言

在前端开发中,设计模式是一种常用的解决软件设计问题的方法,它们提供了可重用的解决方案,帮助我们构建可维护、可扩展的应用程序。下面我将介绍几种常见的设计模式,并对比分析它们的优缺点以及使用案例

关于设计模式

  1. 观察者模式(Observer Pattern)

    • 描述:观察者模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,它的所有依赖对象都会得到通知并自动更新。
    • 优点:降低了对象之间的耦合性,使代码更加灵活和可维护。可以实现事件驱动的编程,适用于需要及时更新多个相关对象的场景。
    • 缺点:容易导致系统中观察者过多,增加了维护的复杂性。如果观察者和主题之间相互依赖,可能会造成循环引用问题。
    • 使用案例:Vue.js 的数据响应系统就是基于观察者模式实现的,通过监听数据的变化来自动更新视图。
  2. 单例模式(Singleton Pattern)

    • 描述:单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。
    • 优点:节省系统资源,提高性能。全局访问点使得实例可以被其他对象方便地访问。
    • 缺点:可能会导致代码耦合性增加,不利于扩展和测试。违反了单一职责原则,一个类负责创建实例和管理状态。
    • 使用案例:Redux 中的 Store 就是一个典型的单例模式,整个应用共享同一个数据状态。
  3. 工厂模式(Factory Pattern)

    • 描述:工厂模式定义了一个创建对象的接口,但由子类决定具体实例化哪个类。通过工厂类来创建对象,而不是直接调用构造函数。
    • 优点:将对象的创建和使用分离,符合开闭原则,降低了代码的耦合性。可以根据需要灵活地创建不同类型的对象。
    • 缺点:增加了代码的复杂度,引入了额外的类。如果需要创建的对象非常多,工厂类可能会变得很庞大。
    • 使用案例:React 中的组件工厂函数 createElement 就是工厂模式的应用,根据传入的参数动态地创建组件。
  4. 适配器模式(Adapter Pattern)

    • 描述:适配器模式将一个类的接口转换成客户端所期望的另一个接口,使得原本不兼容的类能够一起工作。
    • 优点:增加了代码的灵活性和复用性,将不同接口进行适配,减少了代码的修改。可以解决旧代码和新代码的兼容性问题。
    • 缺点:增加了代码的复杂度,可能导致过多的适配器类。因为适配器需要对接口进行转换,会稍微降低性能。
    • 使用案例:在 JavaScript 中,使用 Promises 可以将回调函数的异步模式适配成 Promise 的链式调用模式。

实际例子

假设我们正在开发一个简单的计时器应用,需要实现以下功能:

  1. 用户可以点击开始按钮开始计时。
  2. 计时器每秒钟更新一次,并通知其他对象。
  3. 其他对象接收到通知后,更新显示的计时器数值。

首先,我们需要实现一个主题(Subject)对象,它负责管理所有的观察者并在状态变化时通知它们:

class Subject {
    constructor() {
      this.observers = [];
    }
  
    addObserver(observer) {
      this.observers.push(observer);
    }
  
    removeObserver(observer) {
      const index = this.observers.indexOf(observer);
      if (index > -1) {
        this.observers.splice(index, 1);
      }
    }
  
    notifyObservers() {
      for (let observer of this.observers) {
        observer.update();
      }
    }
  }

然后,我们定义一个具体的观察者(Observer)类,它用于更新显示的计时器数值:

class TimerDisplay {
    constructor(subject) {
      this.subject = subject;
      this.time = 0;
    }
  
    update() {
      this.time++;
      console.log(`Timer: ${this.time}`);
    }
  }

最后,我们创建主题和观察者对象,并建立它们之间的关系:

const subject = new Subject();
const display = new TimerDisplay(subject);

subject.addObserver(display);

// 每秒更新一次计时器数值并通知观察者
setInterval(() => {
  subject.notifyObservers();
}, 1000);

在上述代码中,我们通过观察者模式实现了计时器应用的功能。主题对象 Subject 维护了一个观察者列表,并提供了添加、删除和通知观察者的方法。观察者 TimerDisplay 实现了 update 方法,在每次被通知时更新计时器数值。

个人思考(观察者模式)

  1. 解耦合和可扩展性:观察者模式能够解耦主题和观察者,使它们之间的依赖关系变得松散。这样一来,当需要添加新的观察者时,我们只需创建一个新的观察者对象并将其注册到主题上,而无需修改主题或其他观察者的代码。这种解耦合的设计使得系统更加灵活和可扩展。
  2. 实时数据更新:观察者模式适用于需要实时更新数据的场景,如聊天应用中的消息通知、股票行情的实时更新等。当主题状态改变时,所有订阅该主题的观察者将立即收到通知,并进行相应的处理。这使得我们能够在不刷新页面的情况下获取最新的数据,并将其实时展示给用户。
  3. 事件驱动编程:观察者模式可以实现事件驱动的编程范式,即当某个事件发生时,我们可以触发相应的操作。在前端开发中,我们经常需要监听用户的交互行为或页面上的各种事件,并根据这些事件作出相应的响应。通过观察者模式,我们可以将这些事件和对应的处理逻辑进行解耦,使代码更加清晰和可维护。
  4. 状态管理库的实现:许多前端框架和库使用观察者模式来实现状态管理,如 React 中的 Redux、Vue.js 中的 Vuex。通过观察者模式,我们可以集中管理应用的状态,并在状态发生变化时自动更新相关的组件或视图。这种集中式的状态管理可以简化代码的复杂性,提高应用的性能和可维护性。

文章仅为个人学习笔记,如有错误,欢迎指正。