Patrones de diseño en TypeScript: ejemplos y aplicació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
```html

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



Los patrones de diseño (design patterns) son soluciones probadas para problemas típicos en el desarrollo de software. En TypeScript, gracias al tipado estricto y las capacidades de la POO, muchos patrones se implementan de manera especialmente elegante y segura. En este artículo analizaremos cuatro patrones clave con ejemplos de código reales que te ayudarán a escribir código más flexible y mantenible.



1. Singleton (Instancia única)



El patrón Singleton garantiza que una clase tenga una única instancia y proporciona un punto de acceso global a ella. En TypeScript, esto es especialmente útil para gestionar la configuración de la aplicación o las conexiones a bases de datos.



Implementación usando un constructor privado y un método estático:



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

private constructor() { this.connection = 'PostgreSQL connected'; }

public static getInstance(): DatabaseConnection { if (!DatabaseConnection.instance) { DatabaseConnection.instance = new DatabaseConnection(); } return DatabaseConnection.instance; }

public query(sql: string): void { console.log(`Executing query: ${sql} on ${this.connection}`); }}

// Usoconst db1 = DatabaseConnection.getInstance();const db2 = DatabaseConnection.getInstance();console.log(db1 === db2); // true - el mismo objetodb1.query('SELECT * FROM users');


Cuándo usarlo: para loggers, cachés, pools de hilos, configuraciones de aplicación. Evita Singleton para estados que puedan cambiar en entornos multihilo.



2. Factory Method (Método de fábrica)



Factory Method define una interfaz para crear un objeto, pero permite que las subclases modifiquen el tipo de objeto creado. En TypeScript, esto se combina perfectamente con interfaces y clases abstractas.



Ejemplo de creación de diferentes tipos de notificaciones:



interface Notification {  send(message: string): void;}

class EmailNotification implements Notification { public send(message: string): void { console.log(`Email sent: ${message}`); }}

class SMSNotification implements Notification { public send(message: string): void { console.log(`SMS sent: ${message}`); }}

abstract class NotificationFactory { public abstract createNotification(): Notification;

public notifyUser(message: string): void { const notification = this.createNotification(); notification.send(message); }}

class EmailNotificationFactory extends NotificationFactory { public createNotification(): Notification { return new EmailNotification(); }}

class SMSNotificationFactory extends NotificationFactory { public createNotification(): Notification { return new SMSNotification(); }}

// Usoconst factory: NotificationFactory = new EmailNotificationFactory();factory.notifyUser('Your order has been shipped!');


Cuándo usarlo: cuando no se sabe de antemano qué clase concreta se necesitará, o cuando la lógica de creación del objeto es compleja y debe centralizarse.



3. Observer (Observador)



Observer define una relación "uno a muchos" entre objetos: cuando cambia el estado de un objeto, todos los objetos dependientes son notificados automáticamente. En TypeScript, esto se implementa a menudo con genéricos para tipificar los eventos.



Ejemplo de un sistema de suscripciones a noticias:



interface Observer<T> {  update(data: T): void;}

class NewsPublisher<T> { private observers: Observer<T>[] = [];

public subscribe(observer: Observer<T>): void { this.observers.push(observer); }

public unsubscribe(observer: Observer<T>): void { this.observers = this.observers.filter(obs => o ```

Blogs

Book Recommendations