Decoradores e Inyección de Dependencias en Node.js
Clase 7 de 26 • Curso de Node.js Avanzado
Resumen
El uso de patrones como decorators e inyección de dependencias es actualmente esencial en el desarrollo moderno con JavaScript, especialmente en frameworks como Fastify y Next.js. Entender cómo implementar estos patrones permite crear aplicaciones más ordenadas y flexibles, extendiendo funcionalidades de forma dinámica y modular.
¿Qué son los decorators en JavaScript?
El patrón decorator es una técnica utilizada para añadir funcionalidad adicional a objetos ya existentes. En Node.js, y particularmente con Fastify, este patrón permite extender de forma dinámica los objetos, por ejemplo, el objeto request o response.
La principal ventaja de este patrón es que puedes agregar funciones personalizadas al objeto en cualquier parte del ciclo de vida de una petición, logrando mayor modularidad y dinamismo en el desarrollo de tus aplicaciones.
¿Qué es la inyección de dependencias y cómo funciona?
La inyección de dependencias es otro patrón clave en el desarrollo moderno, especialmente popularizado por frameworks como Next.js. La idea detrás de este patrón es desacoplar componentes y funcionalidades dentro de una aplicación, permitiéndote manejar dependencias externas de manera eficiente y escalable.
En Next.js, este patrón se ejemplifica claramente en proveedores de seguridad, donde diversas implementaciones son inyectadas en la aplicación según las necesidades específicas. Este método fomenta la separación de responsabilidades y facilita la gestión de cambios en el código.
¿Cómo combinas decorators con inyección de dependencias?
Combinar estos dos patrones puede incrementar significativamente la capacidad de organización y escalabilidad en tu aplicación. Un ejemplo práctico de cómo implementar y combinar ambos patrones en JavaScript es el siguiente:
Creación de la clase base
Primero, definimos una clase base denominada DataService
que realizará una operación básica con datos:
class DataService {
processData(data) {
return data.map(item => item * 2);
}
}
Implementación del decorator
Luego, creamos un decorator para añadir automáticamente logging. El decorator, en este ejemplo DataServiceWithLogging
, añade funcionalidad sin modificar el comportamiento original:
class DataServiceWithLogging {
constructor(dataService, logger) {
this.dataService = dataService;
this.logger = logger;
}
processData(data) {
this.logger.log('iniciando procesamiento');
const resultado = this.dataService.processData(data);
this.logger.log('finalizando procesamiento');
return resultado;
}
}
Definición e inyección del logger
Luego definimos un objeto logger sencillo que implementará la dependencia que se va a inyectar, en este caso un logger que imprime mensajes en consola:
class Logger {
log(message) {
console.log('logger:', message);
}
}
Uso del decorator con inyección de dependencias
Finalmente, utilizamos nuestro servicio decorado e inyectamos el logger mediante las instancias creadas:
const baseService = new DataService();
const logger = new Logger();
const decoratedService = new DataServiceWithLogging(baseService, logger);
const inputData = [1, 2, 3, 4];
const processedData = decoratedService.processData(inputData);
console.log('resultado procesado:', processedData);
Este ejemplo muestra claramente la sinergia de ambos patrones, generando código organizado, fácil de mantener y extensible. Los decorators aumentan funcionalidad sin alterar la esencia original, mientras que la inyección de dependencias asegura una gestión más sencilla y efectiva de componentes y funciones dentro del proyecto.
¿Te ha resultado útil este ejemplo práctico de decorators e inyección de dependencias? ¡Comparte tus comentarios y experiencias!