Combinando patrones Singleton y Factory para crear un logger

Clase 4 de 26Curso de Node.js Avanzado

Resumen

Crear un logger eficiente en JavaScript es posible combinando dos patrones esenciales: Singleton y Factory. Esta combinación permite gestionar registros o logs de manera centralizada y versátil, adaptándose fácilmente a las necesidades específicas del proyecto.

¿Qué es el patrón singleton y cómo implementarlo en JavaScript?

El patrón Singleton asegura que una clase tenga una única instancia en la aplicación. En JavaScript, puedes lograr esto definiendo una clase que verifica si ya existe una instancia antes de crear una nueva.

Un ejemplo claro es el siguiente:

class Logger {
  constructor() {
    if (!Logger.instance) {
      this.logs = [];
      Logger.instance = this;
    }
    return Logger.instance;
  }

  log(message) {
    const timestamp = new Date();
    const logObj = { message, timestamp };
    this.logs.push(logObj);
    console.log(logObj);
  }

  getLogs() {
    return this.logs;
  }
}

module.exports = Logger;

Al usar Singleton, se asegura que cada vez que se instancia la clase Logger sea la misma instancia, centralizando los logs en un solo lugar.

¿Cómo funciona el patrón factory para crear diferentes tipos de loggers?

El patrón Factory permite crear diferentes tipos de objetos a partir de una sola clase o interfaz. Así puedes crear fácilmente loggers específicos según tus necesidades.

Este ejemplo muestra cómo crear dos tipos de logger con un Factory:

const Logger = require('./logger');
const loggerInstance = new Logger();

class ConsoleLogger {
  constructor() {
    this.logger = loggerInstance;
  }

  log(message) {
    console.log(`console logger: ${message}`);
    this.logger.log(message);
  }
}

class FileLogger {
  constructor() {
    this.logger = loggerInstance;
  }

  log(message) {
    console.log(`file logger: ${message}`);
    this.logger.log(message);
  }
}

class LoggerFactory {
  static createLogger(type) {
    if (type === 'console') return new ConsoleLogger();
    if (type === 'file') return new FileLogger();
  }
}

module.exports = LoggerFactory;

¿Cómo combinar los patrones singleton y factory en una aplicación real?

Integrando ambos patrones, puedes manejar logs efectivamente en diferentes modalidades (consola, archivo, etc.), sin perder la centralización.

Aquí está el archivo principal para implementar estos conceptos combinados:

const LoggerFactory = require('./loggerFactory');
const Logger = require('./logger');
const loggerInstance = new Logger();

const consoleLogger = LoggerFactory.createLogger('console');
const fileLogger = LoggerFactory.createLogger('file');

consoleLogger.log('esto es un mensaje de en consola');
fileLogger.log('esto es un mensaje de log en archivo');

loggerInstance.getLogs().forEach(log => console.log(log));

Al ejecutar este código, verás cómo cada tipo de logger maneja su función específica, y todos los logs se mantienen en una ubicación centralizada gracias al patrón singleton.

¿Te animas a completar el reto propuesto? Cuéntame tus resultados en los comentarios.