首页  >  文章  >  web前端  >  Node.js 中需要了解的五种设计模式

Node.js 中需要了解的五种设计模式

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-10-07 18:17:30396浏览

嘿那里!

我最近浏览了多个知识资源,以了解更多有关 Node.js 中流行的设计和架构模式的信息。我的目标主要是服务器(后端)端,但当我浏览它们时,我发现它们与浏览器(前端)框架有很多相似之处。其中一些甚至直接在框架中使用,对此我更高兴,因为我在不知情的情况下已经使用它们了?

有很多(真的很多)设计模式可供您使用,因此在本文中,我决定选择其中 10 个并更详细地解释它们。

享受吧!

?什么是设计模式?

设计模式是经过验证和久经考验的解决方案,可以解决我们作为开发人员每天遇到的问题。这些模式有助于推广最佳实践并实施结构化方法来解决设计和开发软件架构时的日常问题。软件工程师可以使用这些模式开发可维护、安全且稳定的系统。

Node.js 由于其灵活性,不会强迫您遵循某些模式,而是让您可以自由地选择任务所需的模式。这就是为什么我认为它今天被如此广泛使用(顺便说一下,这要感谢 JavaScript :D)。

✅ Node.js 中五种流行的设计模式

下面,您将看到我喜欢的 5 种精选设计模式的列表。

辛格尔顿

这一模式是关于只能有一个实例并提供对其的全局访问的类。 Node.js 中的模块可以在应用程序中缓存和共享,这将有助于提高资源效率。这种单例模式的一个常见示例是用于连接某些第三方服务(例如数据库、缓存服务、电子邮件提供商等)的模块,该模块在 Nest.js 框架中广泛使用。让我们看一下下面的例子:


class Redis {
  constructor() {
    this.connection = null;
  }

  static getInstance() {
    if (!Redis. instance) {
      Redis.instance = new Redis(options);
    }

    Return Redis.instance;
  }

  connect() {
    this.connection = 'Redis connected'
  }
}


然后我们可以像下面这样使用它:


const medicine = Redis.getInstance();
const redisTwo = Redis.getInstance();

console.log(redisOne === RedisTwo); // it will result to `true`

redisOne.connect();

console.log(redisOne.connection) // 'Redis connected'
console.log(redisTwo.connection) // 'Redis connected'


这种方法确保只有一个与 Redis 的连接,并防止重复连接。

工厂

使用此模式,您可以创建新对象,而无需指定将创建的对象的类。多亏了它,我们抽象了对象创建,这有助于提高代码的可读性和可重用性:


class Character {
  constructor(name, health) {
    this.name = name;
    this.health = health;
  }
}

class CharacterFactory {
  createCharacter(name) {
    switch(name) {
      case 'mage': 
        return new Character('Powerful Mage', 8);
      case 'warrior':
        return new Character('Courageous Warrior', 10);
      case 'rogue':
        return new Character('Sneaky Rogue', 9)
      default:
        return new Error('Unknown character');
    }
  }
}


然后我们可以像下面这样使用它:


const characterFactory = new CharacterFactory();

const mage = characterFactory.createCharacter('mage');
const warrior = characterFactory.createCharacter('warrior');

console.log(mage.name) // Powerful Mage
console.log(warrior.name) // Courageous Warrior


这种方法允许该工厂的使用者使用工厂代码,而不是直接使用Character类构造函数。

观察者

此模式的工作方式是,您将拥有一个实体来管理称为观察者的依赖元素列表,并在状态发生变化时通知它们。该模式在 Vue.js 框架中广泛使用,实现方式如下:


class Topic {
  constructor() {
    this.observers = []; 
  }

  subscribe(observer) {
    this.observers.push(observer);
  }

  unsubscribe(observer) {
    this.observers = this.observers.filter(o => o !== observer);
  }

  notify(data) {
    this.observers.forEach(o => o.update(data));
  }
}

class Observer {
  constructor(name) {
    this.name = name;
  }

  update(data) {
    console.log(`${this.name} received ${data}`);
  }
}


您可以像下面这样使用它:


const topic = new Topic();

const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');

topic.subscribe(observer1);
topic.subscribe(observer2);

topic.notify('Hello World');
// Observer 1 received Hello World 
// Observer 2 received Hello World

topic.unsubscribe(observer2);

topic.notify('Hello Again');
// Observer 1 received Hello Again


对于事件处理和异步工作流程来说,这是一种非常有用的模式,允许更新多个对象,而无需将发布者与订阅者耦合。

装饰者

此模式对于使用新功能扩展现有功能而不影响初始/原始实例非常有用。由于 TypeScript 的全面支持,它在 Nest.js 框架中被广泛使用,但在常规 Node.js 中,它可以用于以下用途:


class Character {
  constructor() {
    this.endurance = 10;
  }

  getEndurance() {
    return this.endurance;
  }
}

class CharacterActions {
  constructor(character) {
    this.character = character;
  }

  attack() {
    this.character.endurance -= 2;
  }

  rest() {
    this.character.endurance += 1; 
  }
}


然后可以像下面这样使用:


const character = new Character();

console.log(character.getEndurance()); // 10

const characterWithActions = new CharacterActions(character);

characterWithActions.attack(); // - 2
characterWithActions.rest(); // + 1

console.log(characterWithActions.character.getEndurance()); // 9


通过使用这种模式,我们可以轻松扩展现有的类,而不影响其核心功能。

依赖注入

在此模式中,类或模块从外部源接收依赖项,而不是在内部注册它们。这种方法允许从系统中提取某些可重用元素,以便于测试和维护。它在 Nest.js 框架中被广泛使用。可以像下面这样实现:


class UserService {
  constructor(databaseService, loggerService) {
    this.db = databaseService;
    this.logger = loggerService;
  }

  async getUser(userId) {
    const user = await this.db.findUserById(userId);
    this.logger.log(`Fetched user ${user.name}`);
    return user;
  }
}


然后,您可以像下面这样使用它:


const databaseService = new Database();
const loggerService = new Logger();

const userService = new UserService(databaseService, loggerService);

userService.getUser(1);


这种方法允许您将系统的元素提取到可以在需要时注入的独立实体中。

?了解更多

如果您想了解更多有关 Vue、Nuxt、JavaScript 或其他有用技术的信息,请点击此链接或点击下图查看 VueSchool:

Five Design Patterns to know in Node.js

它涵盖了构建现代 Vue 或 Nuxt 应用程序时最重要的概念,可以帮助您完成日常工作或业余项目?

✅ 总结

干得好!您刚刚了解了某些设计模式在 Node.js 中的工作原理以及如何实现它们。

保重,下次再见!

一如既往地快乐编码?️

以上是Node.js 中需要了解的五种设计模式的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn