Привет!
Недавно я просмотрел несколько информационных ресурсов, чтобы узнать больше о популярных шаблонах проектирования и архитектуры в 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
Этот подход позволяет потребителям этой фабрики использовать код фабрики вместо прямого использования конструктора класса символов.
наблюдатель
Этот шаблон работает таким образом, что у вас есть сущность, которая управляет списком зависимых элементов, называемых наблюдателями, и уведомляет их об изменении состояния. Этот шаблон широко используется в среде 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
Это очень полезный шаблон для обработки событий и асинхронных рабочих процессов, который позволяет обновлять несколько объектов без привязки издателя к подписчикам.
Декоратор
Этот шаблон очень полезен для расширения существующей функциональности за счет новой, не затрагивая исходные/исходные экземпляры. Он широко используется в фреймворке Nest.js благодаря полной поддержке TypeScript, но в стандартном 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, нажав здесь. связь или нажав на картинку ниже:
Он охватывает наиболее важные концепции создания современных приложений Vue или Nuxt, которые могут помочь вам в повседневной работе или побочных проектах ?
✅Резюме
Отличная работа! Вы только что узнали, как некоторые шаблоны проектирования работают в Node.js и как их реализовать.
Берегите себя и увидимся в следующий раз!
И как всегда приятного кодирования ?️