Padrões de Projeto em TypeScript: exemplos e aplicação

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Padrões de Projeto em TypeScript: Guia Prático



Padrões de projeto (design patterns) são soluções comprovadas para problemas recorrentes no desenvolvimento de software. Em TypeScript, graças à tipagem forte e aos recursos de POO, muitos padrões são implementados de forma especialmente elegante e segura. Neste artigo, vamos analisar quatro padrões-chave com exemplos reais de código que ajudarão você a escrever um código mais flexível e sustentável.



1. Singleton (Instância Única)



O padrão Singleton garante que uma classe tenha apenas uma instância e fornece um ponto de acesso global a ela. Em TypeScript, isso é especialmente útil para gerenciar a configuração da aplicação ou conexões com o banco de dados.



Implementação usando construtor privado e 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 - mesmo objetodb1.query('SELECT * FROM users');


Quando usar: para loggers, caches, pools de threads, configurações da aplicação. Evite Singleton para estados que podem mudar em ambiente multithread.



2. Factory Method (Método Fábrica)



O Factory Method define uma interface para criar um objeto, mas permite que as subclasses alterem o tipo do objeto criado. Em TypeScript, isso combina perfeitamente com interfaces e classes abstratas.



Exemplo de criação de diferentes tipos de notificações:



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!');


Quando usar: quando não se sabe antecipadamente qual classe concreta será necessária, ou quando a lógica de criação do objeto é complexa e deve ser centralizada.



3. Observer (Observador)



O Observer define uma relação "um para muitos" entre objetos: quando o estado de um objeto muda, todos os objetos dependentes são notificados automaticamente. Em TypeScript, isso é frequentemente implementado com genéricos para tipagem de eventos.



Exemplo de sistema de assinaturas de notícias:



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