Pular para o conteúdo principal

TDD / BDD / DDD

TDD

Test Driven Development

O TDD é uma metodologia de desenvolvimento de software que segue um ciclo iterativo e incremental de três etapas: escrever um teste automatizado que falhe, implementar o código necessário para fazer o teste passar e, finalmente, refatorar o código para melhorar sua estrutura e qualidade, mantendo os testes passando.
Ele segue um ciclo contínuo de pequenas iterações, onde cada iteração adiciona um pequeno pedaço de funcionalidade ao sistema.

Observação: Não é uma abordagem para realizar testes.

Escrever Teste (Red): O ciclo começa escrevendo um teste automatizado que descreve o comportamento desejado da funcionalidade a ser implementada. Este teste inicialmente falhará, pois o código de produção correspondente ainda não foi escrito.

Implementar Código (Green): Em seguida, escrevemos o código mínimo necessário para fazer o teste passar. O foco aqui é na funcionalidade necessária para satisfazer as condições do teste.

Refatorar (Refactor): Com o teste passando, podemos refatorar o código para melhorar sua estrutura, clareza e eficiência. Este passo garante que o código permaneça limpo e sustentável ao longo do tempo.

TDD

  • O teste de uma funcionalidade é escrito antes do código que o implementa.
  • Em geral são utilizados testes unitários, caixa-branca, testes de integração ou testes de aceitação.
  • Parte dos métodos ágeis,como o Extreme Programming.

BDD

Behaviour Drive Development
(Desenvolvimento orientado por comportamento)

É uma técnica de desenvolvimento de software que visa integrar regras de negócios com linguagem de programação, focando nas interações e comportamentos do sistema.

  • Evolução do TDD, enfatizando colaboração e testes antes do código.
  • Usa linguagem ubíqua (comum a todos os envolvidos definidos pelas palavras-chave: Given, When e Then).
  • Comportamentos específicos do software do ponto de vista do usuário.
  • Baseado em testes de caixa preta.
  • A documentação é atualizada automaticamente a cada ciclo.

Foco em requisitos e comportamento esperado, não na implementação!

Ferramentas:

  1. Cucumber (Traduzem cenários de comportamento escritos em Gherkin diretamente em testes automatizados executáveis).
  2. JBehave (usa sua própria sintaxe para descrever cenários de testes).

DDD

Domain Driven Design
(Design orientado a domínio)

Domínio é a área de conhecimento, problema de negócio ao qual pretente-se aplicar a solução de software.

É uma abordagem de desenvolvimento de software para lidar com comportamentos complexos na construção de um software. Não foca na tecnologia.

Foco no domínio do negócio, não na tecnologia.
✅ Usa linguagem ubíqua para alinhar desenvolvedores e especialistas do domínio.
✅ Divide o sistema em contextos delimitados (Bounded Contexts).

Padrões DDD

Esses padrões não são técnicos, são formas de representar regras do negócio no código.

Esses padrões visam representar e organizar o modelo de domínio, garantindo a consistência e expressividade das regras de negócio dentro da camada de domínio.

  1. Value Object (VO)
    São objetos que representam um conceito (ex: CPF, endereço, dinheiro), não têm identidade e são imutáveis.
    Você não se importa com “quem” é, mas com o valor que ele carrega.
    Ex: Dois CPFs iguais representam o mesmo VO.

  2. Entity
    São objetos que têm identidade única e ciclo de vida próprio.
    Mesmo que seus atributos mudem, a identidade continua a mesma.
    Ex: um cliente pode trocar de nome ou endereço, mas ainda é o mesmo cliente (ID).

  3. Aggregate
    É um conjunto de Entities e VOs que é tratado como uma unidade de consistência e transação.
    Sempre tem uma raiz (Aggregate Root), que é a única porta de entrada para acessar ou modificar o conjunto.
    Ex: um Pedido (Aggregate Root) com seus Itens (Entities internas).

ACL

Anti-Corruption Layer

É uma camada de tradução e proteção entre dois sistemas (ou bounded contexts) com modelos de domínio diferentes.
Objetivo: Evitar que o modelo externo interfira ou corrompa o seu modelo interno.

Pode ser usada tanto com comunicação síncrona (ex: REST, gRPC) quanto assíncrona (ex: eventos, filas). Não depende do tipo de comunicação.

Exemplo:

Seu sistema usa CPF para identificar clientes, mas o sistema externo usa ID numérico. A ACL traduz o ID externo para o CPF interno antes de passar os dados pro teu domínio.

ACL

O diagrama mostra dois subsistemas: o A conversa com o B usando uma ACL.
O subsistema A fala com a ACL no seu próprio modelo, e a ACL traduz pro modelo do B.
Toda a lógica de conversão fica na ACL, que pode ser um pedaço do app ou um serviço separado.

dica

A ACL é tipo um “tradutor juramentado” entre sistemas com línguas (modelos) diferentes. Ela impede que um sistema zoado bagunce o seu código certinho. Funciona com chamadas síncronas ou assíncronas — tanto faz, ela tá ali pra blindar teu domínio.