Boas Práticas e Padrões de Código


Aqui são apresentadas práticas para escrever código claro, legível e de fácil manutenção, garantindo consistência, qualidade e robustez.

As recomendações aplicam princípios de S.O.L.I.D, Object Calisthenics e outras técnicas de engenharia de software orientadas à coesão, baixo acoplamento e legibilidade, promovendo sistemas mais testáveis, escaláveis e fáceis de evoluir.

1. Nomes Claros e Descritivos

Ruim

function calc(u) {
  return u.age * 365;
}

Bom

function calculateUserAgeInDays(user: User): number {
  return user.age * 365;
}

Regra: nomes devem revelar intenção. Evite abreviações e termos genéricos que escondem o propósito.


2. Funções Pequenas e Coesas

Ruim

function processOrder(order: Order) {
  validateOrder(order);
  saveToDatabase(order);
  sendEmail(order.user.email, "Order processed");
}

Bom

function processOrder(order: Order) {
  validateOrder(order);
  persistOrder(order);
  notifyUser(order.user);
}

function persistOrder(order: Order) {
  saveToDatabase(order);
}

function notifyUser(user: User) {
  sendEmail(user.email, "Order processed");
}

Regra: cada função deve ter apenas uma responsabilidade (SRP).


3. Evite Comentários Desnecessários

Ruim

// Multiplica idade por 365 para calcular idade em dias
function calculateAge(user: User) {
  return user.age * 365;
}

Bom

function calculateAgeInDays(user: User): number {
  return user.age * 365;
}

Regra: comentários só para regras complexas ou exceções. Código claro elimina comentários redundantes.


4. Use DTOs e Mappers

Ruim

function createUser(body: any) {
  const user = new User();
  user.name = body.n;
  user.email = body.e;
  return user;
}

Bom

class UserMapper {
  static toEntity(dto: CreateUserDTO): User {
    return new User(dto.name, dto.email);
  }

  static toDTO(user: User): UserResponseDTO {
    return { id: user.id, name: user.name, email: user.email };
  }
}

function createUser(dto: CreateUserDTO): User {
  return UserMapper.toEntity(dto);
}

Regra: separar entrada/saída da lógica de domínio mantém clareza e baixo acoplamento.


5. Tratamento de Erros Claro

Ruim

try {
  saveOrder(order);
} catch (e) {
  console.log("Erro");
}

Bom

try {
  saveOrder(order);
} catch (error) {
  throw new OrderPersistenceException(order.id, error);
}

Regra: trate erros de forma explícita e contextualizada, nunca silenciosa.


6. Evite else (Use Early Return ou Polimorfismo)

Ruim

function getDiscount(price: number, isVip: boolean): number {
  if (isVip) {
    return price * 0.8;
  } else {
    return price * 0.9;
  }
}

Bom

function getDiscount(price: number, isVip: boolean): number {
  if (isVip) return price * 0.8;
  return price * 0.9;
}

Regra: menos níveis de indentação → código mais claro e objetivo.


7. Métodos e Objetos Pequenos

Ruim

class Order {
  constructor(private items: number[], private tax: number) {}

  total(): number {
    let sum = 0;
    for (const item of this.items) {
      sum += item;
    }
    return sum + sum * this.tax;
  }
}

Bom

class Order {
  constructor(private items: number[], private tax: number) {}

  private subtotal(): number {
    return this.items.reduce((sum, item) => sum + item, 0);
  }

  total(): number {
    return this.subtotal() + this.subtotal() * this.tax;
  }
}

Regra: divida lógica em métodos menores e mais focados.