Patrones de diseño en TypeScript: ejemplos e implementación

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Patrones de diseño en TypeScript: de la teoría a la práctica



Los patrones de diseño (Design Patterns) son soluciones probadas para problemas típicos en el desarrollo de software. En el contexto de TypeScript, con su potente sistema de tipos y soporte para POO, muchos patrones clásicos del libro "Gang of Four" (GoF) adquieren una implementación nueva y más elegante. En este artículo, analizaremos tres patrones clave con ejemplos reales en TypeScript que te ayudarán a escribir código más limpio, escalable y mantenible.



1. Patrón creacional: Singleton



Propósito: Garantiza que una clase tenga solo una instancia y proporciona un punto de acceso global a ella.



En TypeScript, la implementación de Singleton es especialmente conveniente gracias a las propiedades estáticas y los constructores privados. Este patrón es ideal para gestionar conexiones a bases de datos, loggers o cachés.



class DatabaseConnection {    private static instance: DatabaseConnection;    private connectionString: string;

private constructor(connectionString: string) { this.connectionString = connectionString; console.log(`Conexión creada a: ${connectionString}`); }

public static getInstance(connectionString?: string): DatabaseConnection { if (!DatabaseConnection.instance) { if (!connectionString) { throw new Error("Connection string required for first initialization"); } DatabaseConnection.instance = new DatabaseConnection(connectionString); } return DatabaseConnection.instance; }

public query(sql: string): void { console.log(`Ejecutando consulta: ${sql} en ${this.connectionString}`); }}

// Usoconst db1 = DatabaseConnection.getInstance("postgres://localhost:5432/mydb");const db2 = DatabaseConnection.getInstance();

console.log(db1 === db2); // true — el mismo objetodb1.query("SELECT * FROM users");


Importante: En TypeScript se pueden usar readonly y genéricos para implementaciones más flexibles. Sin embargo, recuerda que Singleton puede complicar las pruebas — considera la inyección de dependencias (DI) como alternativa.



2. Patrón estructural: Decorator



Propósito: Añade dinámicamente nuevas responsabilidades a un objeto sin modificar su estructura. En TypeScript, los decoradores son una característica de primera clase del lenguaje (experimental en ES5, pero ampliamente utilizada en Angular y NestJS).



Veamos un ejemplo con un decorador para registrar llamadas a métodos:



// Interfaz objetivointerface ILogger {    log(message: string): void;}

// Clase baseclass SimpleLogger implements ILogger { public log(message: string): void { console.log(`[LOG]: ${message}`); }}

// Decorador (clase envoltorio)class TimestampDecorator implements ILogger { private logger: ILogger;

constructor(logger: ILogger) { this.logger = logger; }

public log(message: string): void { const timestamp = new Date().toISOString(); this.logger.log(`[${timestamp}] ${message}`); }}

// Decorador para formateoclass UpperCaseDecorator implements ILogger { private logger: ILogger;

constructor(logger: ILogger) { this.logger = logger; }

public log(message: string): void { this.logger.log(message.toUpperCase()); }}

// Usolet logger: ILogger = new SimpleLogger();logger.log("Hola mundo"); // [LOG]: Hola mundo

logger = new TimestampDecorator(logger);logger = new UpperCaseDecorator(logger);logger.log("los decoradores funcionan"); // [LOG]: [2025-01-15T10:30:00.000Z] LOS DECORADORES FUNCIONAN


Consejo: En TypeScript también están disponibles los decoradores de clases y propiedades (sintaxis @decorator

Blogs

Book Recommendations