Привет!
Недавно я просмотрел несколько информационных ресурсов, чтобы узнать больше о популярных шаблонах проектирования и архитектуры в 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 и как их реализовать.
Берегите себя и увидимся в следующий раз!
И как всегда приятного кодирования ?️