Padrões de Projeto em TypeScript: exemplos e implementaçã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 Design em TypeScript: da teoria à prática



Padrões de Design (Design Patterns) são soluções comprovadas para problemas típicos no desenvolvimento de software. No contexto do TypeScript, com seu poderoso sistema de tipos e suporte a OOP, muitos padrões clássicos do livro "Gang of Four" (GoF) ganham uma implementação nova e mais elegante. Neste artigo, vamos analisar três padrões-chave com exemplos reais em TypeScript que ajudarão você a escrever um código mais limpo, escalável e de fácil manutenção.



1. Padrão Criacional: Singleton



Finalidade: Garante que uma classe tenha apenas uma instância e fornece um ponto de acesso global a ela.



Em TypeScript, a implementação do Singleton é particularmente conveniente graças às propriedades estáticas e construtores privados. Este padrão é ideal para gerenciar conexões de banco de dados, loggers ou caches.



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

private constructor(connectionString: string) { this.connectionString = connectionString; console.log(`Conexão criada para: ${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(`Executando consulta: ${sql} em ${this.connectionString}`); }}

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

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


Importante: Em TypeScript, você pode usar readonly e genéricos para implementações mais flexíveis. No entanto, lembre-se de que o Singleton pode dificultar os testes — considere a injeção de dependência (DI) como alternativa.



2. Padrão Estrutural: Decorator



Finalidade: Adiciona dinamicamente novas responsabilidades a um objeto sem alterar sua estrutura. Em TypeScript, decorators são um recurso de primeira classe da linguagem (experimental no ES5, mas amplamente usado em Angular e NestJS).



Vamos considerar um exemplo com um decorator para registrar chamadas de métodos:



// Interface alvointerface ILogger {    log(message: string): void;}

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

// Decorator (classe wrapper)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}`); }}

// Decorator para formataçãoclass 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("Olá mundo"); // [LOG]: Olá mundo

logger = new TimestampDecorator(logger);logger = new UpperCaseDecorator(logger);logger.log("decorators funcionam"); // [LOG]: [2025-01-15T10:30:00.000Z] DECORATORS FUNCIONAM


Dica: Em TypeScript, também estão disponíveis decorators de classe e propriedade (sintaxe @decorator

Blogs

Book Recommendations