3. Linguagem Ubíqua - A Base da Colaboração

3.1. A Falha da Comunicação Tradicional

Como vimos na seção anterior, existe uma barreira comunicacional histórica entre equipes de tecnologia e especialistas de negócio. Essa barreira se manifesta de várias formas:

Do lado do negócio:

  • “É só um botãozinho”
  • “Quero um relatório simples”
  • Trivialização das demandas técnicas

Do lado da TI:

  • “Precisamos refatorar a camada de infraestrutura”
  • “O cluster Kubernetes está sobrecarregado”
  • Obscurecimento com jargão técnico

O resultado é um abismo comunicativo onde a colaboração se torna inviável e o software produzido não reflete as reais necessidades da organização.

3.2. A Linguagem Ubíqua como Solução

Um dos conceitos mais revolucionários do DDD é a linguagem ubíqua (ubiquitous language).

🧠 Definição: A linguagem ubíqua é um vocabulário comum, compartilhado entre desenvolvedores e especialistas de negócio, que reflete os conceitos do domínio. Essa linguagem deve ser utilizada no código-fonte, nos testes, na modelagem, na documentação e nas conversas do time.

Ou seja, não se trata apenas de conversar com o cliente usando termos do negócio, trata-se de usar esses mesmos termos nas classes, métodos, pacotes, testes e commits do projeto.

Exemplo prático:

Imagine um sistema de gerenciamento de tarefas. Em vez de:

public class TaskManager {
    public void finishItem(Long id) {
        Item item = repository.findById(id);
        item.setStatus(2); // 2 = concluído?
        repository.save(item);
    }
}

A linguagem ubíqua nos leva a:

public class Task {
    public void complete() {
        if (this.status != TaskStatus.DONE) {
            this.status = TaskStatus.DONE;
            this.events.add(new TaskCompletedEvent(this.id));
        }
    }
}
Conceito de negócio Implementação correta (linguagem ubíqua)
Concluir tarefa task.complete() (não finishItem)
Data limite dueDate (não expiration)
Prioridade Enum Priority.HIGH, MEDIUM, LOW
Categoria Enum Category.STUDY, WORK, etc.

Usar a linguagem ubíqua evita ambiguidades e promove clareza. Se a equipe estiver discutindo “o que acontece quando um responsável conclui uma tarefa atrasada?”, todos devem conseguir visualizar essa lógica diretamente no código, com termos familiares ao negócio.

3.3. Knowledge Crunching: O Processo de Aprendizado Mútuo

A construção da linguagem ubíqua não acontece por acaso. Ela emerge de um processo contínuo chamado Knowledge Crunching (destilação de conhecimento).

Segundo Evans (2003), este processo envolve:

  1. Conversas exploratórias entre desenvolvedores e especialistas de domínio
  2. Modelagem colaborativa onde ambos os lados contribuem
  3. Experimentação com código para validar conceitos
  4. Refinamento contínuo do modelo e da linguagem

O ciclo do Knowledge Crunching:

┌─────────────────┐
│  Conversa com   │
│  especialista   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Novo insight   │
│  sobre domínio  │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Refinar modelo │
│  e linguagem    │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Implementar    │
│  no código      │
└────────┬────────┘
         │
         └─────────────┐
                       │
         ┌─────────────┘
         ▼
    (repetir ciclo)

A linguagem ubíqua evolui com o time. Novas conversas revelam nuances, termos ambíguos são esclarecidos, e o modelo se torna cada vez mais preciso.

3.4. O Perigo de Pular a Linguagem Ubíqua

Quando equipes pulam a fase de construir uma linguagem ubíqua, o resultado é previsível:

Sintomas de ausência de linguagem ubíqua:

  1. Código genérico e vago
    • Classes como DataManager, ItemProcessor, Helper
    • Métodos como doProcess(), handleStuff()
  2. Tradução constante nas reuniões
    • “Quando você diz X, você quer dizer Y no código?”
    • “Aquele campo que você chamou de Z, na verdade é…”
  3. Documentação desatualizada
    • O código não reflete a documentação
    • A documentação não reflete as conversas
    • Ninguém confia em nada
  4. Bugs sutis de interpretação
    • “Cancelamento” vs “Devolução” implementados como a mesma coisa
    • Regras de negócio enterradas em IFs confusos

💡 Reflexão prática: Pegue uma classe do seu projeto atual. Leia os nomes dos métodos em voz alta. Um especialista de negócio conseguiria entender o que cada método faz? Se a resposta for não, você provavelmente não tem linguagem ubíqua.

3.5. Curando a Anemia: Repensando os Setters

Um sintoma comum da falta de linguagem ubíqua é o Modelo de Domínio Anêmico, caracterizado por classes cheias de getters/setters mas sem comportamento real.

Modelo anêmico (sem linguagem ubíqua):

public class Task {
    private String title;
    private int status; // 0=TODO, 1=DOING, 2=DONE
    
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    public int getStatus() { return status; }
    public void setStatus(int status) { this.status = status; }
}

// Lógica de negócio vive em um "service"
public class TaskService {
    public void completeTask(Long id) {
        Task task = repository.findById(id);
        task.setStatus(2); // magic number!
        repository.save(task);
    }
}

Modelo rico (com linguagem ubíqua):

public class Task {
    private final TaskId id;
    private Title title;
    private TaskStatus status;
    private Deadline deadline;
    private List<DomainEvent> events = new ArrayList<>();
    
    public void complete() {
        if (this.status.canTransitionTo(TaskStatus.DONE)) {
            this.status = TaskStatus.DONE;
            this.events.add(new TaskCompletedEvent(this.id, LocalDateTime.now()));
        } else {
            throw new IllegalTaskStateException("Cannot complete a cancelled task");
        }
    }
    
    public boolean isOverdue() {
        return this.deadline.isPast() && !this.status.isDone();
    }
}

Observe como a linguagem ubíqua enriquece o modelo:

  • complete() é mais expressivo que setStatus(2)
  • isOverdue() encapsula regra de negócio
  • TaskStatus é um tipo rico, não um inteiro mágico
  • Invariantes são protegidos (não pode completar tarefa cancelada)

3.6. O Desafio do Idioma: Português vs. Inglês

Uma discussão recorrente em times brasileiros é: devemos codificar em português ou inglês?

Argumentos para Inglês:

  • Padrão internacional
  • Maior portabilidade
  • Facilita contratação global
  • Bibliotecas e frameworks são em inglês

Argumentos para Português:

  • Linguagem ubíqua autêntica (se o negócio fala português)
  • Reduz tradução mental constante
  • Especialistas entendem o código
  • Termos intraduzíveis (Boleto, Pix, CPF/CNPJ)

A Posição do DDD:

Vernon (2013) argumenta que a linguagem ubíqua deve ser na língua do negócio. Se o especialista de domínio fala português, forçar inglês introduz uma camada de tradução — o oposto do objetivo do DDD.

💡 Reflexão crítica: Um sistema financeiro brasileiro que trabalha com “Boleto” deveria ter uma classe Boleto, não BankSlip ou PaymentSlip. A tradução forçada pode até parecer mais “profissional”, mas adiciona complexidade cognitiva desnecessária.

Solução Pragmática:

Muitas equipes adotam uma abordagem híbrida:

  • Infraestrutura técnica (repositories, controllers, configs): inglês
  • Modelo de domínio (entidades, value objects, serviços de domínio): língua do negócio
  • Termos intraduzíveis: sempre na língua original

Exemplo:

// Infraestrutura em inglês
@RestController
@RequestMapping("/api/boletos")
public class BoletoController {
    
    // Domínio em português
    public BoletoResponse emitir(@RequestBody EmissaoBoletoRequest request) {
        Boleto boleto = boletoService.emitirParaCliente(
            new CPF(request.getCpf()),
            new Valor(request.getValor()),
            new DataVencimento(request.getVencimento())
        );
        return converter.toResponse(boleto);
    }
}

3.7. A Linguagem como Ativo Estratégico

A linguagem ubíqua não é apenas uma “boa prática” — ela é um ativo estratégico da organização.

Quando bem construída, ela:

  • Acelera onboarding de novos desenvolvedores
  • Reduz mal-entendidos entre times
  • Documenta implicitamente o sistema
  • Facilita evolução (o código é auto-explicativo)
  • Aproxima negócio e TI (todos falam a mesma língua)

“A linguagem ubíqua é a cola que mantém o modelo de domínio e o código alinhados com o negócio” — Eric Evans

3.8. Conclusão: Da Teoria à Prática

Construir uma linguagem ubíqua requer:

  1. Humildade intelectual — aceitar que não sabemos tudo sobre o negócio
  2. Curiosidade genuína — querer entender o “porquê” das regras
  3. Colaboração ativa — sentar com especialistas regularmente
  4. Coragem de refatorar — mudar código quando a linguagem evolui
  5. Disciplina — manter consistência em todas as camadas

Na próxima seção, exploraremos uma técnica prática para descobrir a linguagem ubíqua de forma colaborativa: o Event Storming.



This site uses Just the Docs, a documentation theme for Jekyll.