Princípios SOLID em TypeScript: teoria e prática do A ao Z

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

Introdução: Por que SOLID é importante para o desenvolvedor TypeScript

SOLID — são cinco princípios fundamentais da programação orientada a objetos, formulados por Robert Martin (Tio Bob). No contexto do TypeScript, que combina tipagem estática e flexibilidade do JavaScript, a aplicação dos princípios SOLID permite criar aplicações escaláveis, testáveis e de fácil manutenção. Neste artigo, analisaremos cada princípio com base teórica e exemplos práticos em TypeScript.



1. Single Responsibility Principle (SRP) — Princípio da Responsabilidade Única

Teoria

Uma classe deve ter apenas um motivo para mudar. Isso significa que cada módulo, classe ou função é responsável por exatamente uma funcionalidade.



Prática em TypeScript

Vamos considerar a violação do SRP no exemplo de uma classe que gerencia usuários e envio de notificações:



// ❌ Violação do SRPclass UserManager {  constructor(private name: string, private email: string) {}

saveUser(): void { console.log(`Usuário ${this.name} salvo no BD`); }

sendWelcomeEmail(): void { console.log(`E-mail de boas-vindas enviado para ${this.email}`); }}


Versão corrigida com separação de responsabilidades:



// ✅ Cumprimento do SRPclass User {  constructor(public name: string, public email: string) {}}

class UserRepository { save(user: User): void { console.log(`Usuário ${user.name} salvo no BD`); }}

class EmailService { sendWelcomeEmail(user: User): void { console.log(`E-mail de boas-vindas enviado para ${user.email}`); }}


2. Open/Closed Principle (OCP) — Princípio Aberto/Fechado

Teoria

Entidades de software devem estar abertas para extensão, mas fechadas para modificação. Em outras palavras, você deve ser capaz de adicionar nova funcionalidade sem alterar o código existente.



Prática em TypeScript

Exemplo com cálculo de descontos para diferentes tipos de clientes:



// ❌ Violação do OCPclass DiscountCalculator {  calculateDiscount(customerType: string, amount: number): number {    if (customerType === 'regular') {      return amount * 0.1;    } else if (customerType === 'premium') {      return amount * 0.2;    } else if (customerType === 'vip') {      return amount * 0.3;    }    return 0;  }}


// ✅ Cumprimento do OCP através de polimorfismointerface DiscountStrategy {  calculate(amount: number): number;}

class RegularDiscount implements DiscountStrategy { calculate(amount: number): number { return amount * 0.1; }}

class PremiumDiscount implements DiscountStrategy { calculate(amount: number): number { return amount * 0.2; }}

class DiscountCalculator { constructor(private strategy: DiscountStrategy) {}

calculate(amount: number): number { return this.strategy.calculate(amount); }}


3. Liskov Substitution Principle (LSP) — Princípio da Substituição de Barbara Liskov

Teoria

Objetos em um programa devem ser substituíveis por instâncias de seus subtipos sem alterar a correção do programa. Em palavras simples: se você tem uma classe base, qualquer herdeiro dela deve funcionar corretamente em todos os lugares onde a classe base é usada.



Prática em TypeScript

Exemplo clássico com figuras geométricas:



// ❌ Violação do LSPclass Rectangle {  constructor(protected width: number, protected height: number) {}

setWidth(width: number): void { this.width = width; }

setHeight(height: number): void { this.height = height; }

getArea(): number { return this.width * this.height; }}

class Square extends Rectangle { setWidth(width: number): void { this.width = width; this.height = width; // Violação! }

setHeight(height: number): vo

Blogs

Book Recommendations