2. Os Três Tipos de Complexidade

Vamos compreender os três tipos de complexidade no desenvolvimento de software e por que essa distinção é fundamental para aplicar DDD corretamente.

A Natureza da Complexidade no Desenvolvimento de Software

Para compreender as raízes do cenário atual do desenvolvimento de software e a necessidade de retomar os fundamentos do DDD, precisamos primeiro entender a definição de ‘complexidade’ no contexto do desenvolvimento de software.

No âmbito da engenharia de software, a análise da complexidade pode ser categorizada em três formas distintas: a complexidade da solução técnica, a complexidade do legado e a complexidade do domínio.

2.1. Complexidade da Solução Técnica (Acidental)

A primeira, referida como Complexidade da Solução Técnica, diz respeito às decisões arquiteturais e instrumentais, tais como:

  • A escolha entre message brokers (e.g., Kafka ou RabbitMQ)
  • A definição de infraestrutura (Kubernetes ou serverless)
  • Decisões sobre bancos de dados (SQL vs. NoSQL)
  • Frameworks e bibliotecas (Spring Boot, Quarkus, Node.js)
  • Protocolos de comunicação (REST, gRPC, GraphQL)

Tais decisões, embora fundamentais para o funcionamento do sistema, configuram-se como complexidade acidental, uma vez que derivam da implementação e não do problema de negócio em si (BROOKS, 1987; JUNIOR, 2020).

O que é complexidade acidental?

Frederick Brooks, em seu artigo seminal “No Silver Bullet” (1987), estabeleceu a distinção fundamental entre:

  • Complexidade Essencial: inerente ao problema que estamos resolvendo
  • Complexidade Acidental: introduzida pela forma como escolhemos resolver o problema

A complexidade técnica é acidental porque poderíamos, em teoria, resolver o mesmo problema de negócio com tecnologias diferentes. Se amanhã surgir uma nova ferramenta ou framework, poderíamos migrar para ela sem que o problema de negócio tenha mudado.

2.2. Complexidade do Legado (Acidental)

Em segundo plano, temos a Complexidade do Legado, originada pela necessidade de manutenção de sistemas preexistentes. O acúmulo de dívida técnica e a dificuldade em evoluir códigos herdados constituem barreiras que também se classificam como complexidade acidental, drenando recursos cognitivos da equipe (VERNON, 2016).

Essa complexidade manifesta-se através de:

  • Código escrito com tecnologias obsoletas ou descontinuadas
  • Falta de documentação ou documentação desatualizada
  • Arquitetura que já não serve aos propósitos atuais
  • Dependências antigas com vulnerabilidades de segurança
  • Conhecimento concentrado em poucos desenvolvedores (ou pior, em nenhum)

A complexidade do legado é particularmente insidiosa porque consome tempo e energia que poderiam ser investidos em entender e resolver o problema de negócio. Cada hora gasta tentando entender por que um sistema legado funciona de determinada maneira é uma hora não gasta compreendendo as reais necessidades dos usuários.

2.3. Complexidade do Domínio (Essencial)

Por fim, destaca-se a Complexidade do Domínio. Esta compreende as regras e desafios intrínsecos ao negócio que o software visa atender.

Segundo Evans (2003), esta é a única complexidade essencial, pois reside no coração do software e justifica o investimento financeiro e o esforço de desenvolvimento para solucionar um problema real.

Exemplos de complexidade do domínio:

Setor Financeiro:

  • Regras de cálculo de juros compostos
  • Legislação tributária e compliance
  • Gestão de risco de crédito
  • Detecção de fraudes

Setor de Saúde:

  • Protocolos médicos e interações medicamentosas
  • Regulamentações de privacidade (HIPAA, LGPD)
  • Fluxos de triagem e atendimento
  • Gestão de leitos e recursos

E-commerce:

  • Regras de precificação dinâmica
  • Cálculo de frete e logística reversa
  • Gestão de estoque distribuído
  • Programas de fidelidade

Observe que nenhum desses problemas desaparece se trocarmos o banco de dados ou migrarmos para Kubernetes. A complexidade do domínio é inerente ao negócio, independentemente de como escolhemos implementar a solução tecnológica.

2.4. O Foco Deslocado: Tecnologia vs. Negócio

Apesar da Complexidade do Domínio ser a complexidade essencial, há uma inclinação natural entre nós, profissionais de tecnologia, em priorizar o gerenciamento das complexidades acidentais, sejam elas técnicas ou legadas.

Por que isso acontece?

A discussão sobre arquitetura, padrões de projeto e ferramentas constitui uma ‘zona de conforto’ cognitiva para nós que somos especialistas técnicos. É mais fácil e mais gratificante debater:

  • “Devemos usar Redis ou Memcached para cache?”
  • “Nossa arquitetura deve ser em camadas ou hexagonal?”
  • “Precisamos migrar para microsserviços ou um monólito modular é suficiente?”

Do que enfrentar questões como:

  • “Por que esse processo de aprovação tem 7 etapas?”
  • “Qual a diferença entre ‘cancelamento’ e ‘devolução’ do ponto de vista do negócio?”
  • “Em que circunstâncias um pedido pode ser editado após confirmação?”

Entretanto, a eficácia do projeto reside na resolução justamente da complexidade essencial. Um sistema pode ter a arquitetura mais sofisticada do mundo, usar as melhores práticas e as tecnologias mais modernas, mas se não resolver corretamente o problema de negócio, ele falhou.

💡 Reflexão: No seu último projeto, sua equipe gastou mais energia tentando configurar o cluster Kubernetes e o ambiente Docker, escolhendo entre diferentes bibliotecas e/ou banco de dados não-relacionais, ou tentando entender profundamente os motivos pelos quais o usuário precisa de determinada funcionalidade? Em outras palavras, seu esforço é maior na Complexidade Acidental ou na Complexidade Essencial? Se a resposta foi a primeira, é importante ficar atento. Talvez sua equipe esteja “vencendo a batalha tecnológica”, mas “perdendo a guerra do negócio”.

2.5. A Barreira da Comunicação

É aqui, neste cenário, que surge um dos entraves mais críticos ao desenvolvimento de software eficaz: a dissonância comunicativa histórica entre as equipes de tecnologia e os especialistas de negócio.

Conforme Evans (2003), quando não há uma linguagem partilhada, o projeto sofre com o custo da ‘tradução’ constante, onde o conhecimento se perde na interpretação entre modelos mentais distintos. É como se cada lado falasse um idioma diferente:

Do lado do negócio:

De um lado, os especialistas de negócio tendem a trivializar demandas complexas, focando na interface ou no resultado imediato:

  • “É só um botãozinho novo”
  • “Puxa um relatório simples pra mim”
  • “Quero um sisteminha ‘tipo o iFood’”

Essa simplificação excessiva ignora a complexidade subjacente e gera atrito com a equipe técnica, que percebe a subestimação do esforço necessário (JUNIOR, 2020).

Do lado da TI:

Em contrapartida, a equipe de Tecnologia da Informação (TI) frequentemente recorre a um “dialeto tecnocrático”, repleto de terminologias incompreensíveis para os especialistas de negócio:

  • “Temos que versionar a API”
  • “Para essa feature precisamos configurar o OAuth2 para gerenciar 2FA”
  • “Nosso cluster Kubernetes está com problema!”

Esse comportamento reflete a tendência dos desenvolvedores de se refugiarem na complexidade acidental, alienando os stakeholders e obscurecendo o modelo de domínio real (VERNON, 2013).

O Resultado: Um Abismo Comunicativo

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

💡 Reflexão: Quando um usuário diz que algo “é simples, é só colocar um botãozinho novo ali”, ele ignora todo o trabalho de backend, banco de dados e testes. Mas olhe o outro lado da moeda: quando respondemos uma demanda com “Preciso refatorar a camada de infraestrutura para injetar a dependência correta”, eles sentem a mesma frustração. O objetivo do DDD é fazer essas duas pessoas se entenderem.

2.6. O Verdadeiro Fundamento do DDD

A proposição fundamental de Evans (2003) visa justamente transpor essa barreira comunicacional e realinhar o foco do desenvolvimento.

O racional do Domain-Driven Design estabelece que a mitigação temporária das complexidades acidentais, inerentes à tecnologia e ao legado, é condição necessária para permitir a imersão profunda na complexidade essencial do domínio.

Para operacionalizar essa diretriz, a metodologia prescreve uma mudança de postura:

O DDD nos pede para:

  1. Deixar um pouco de lado as complexidades técnica e de legado e seus vocabulários
  2. Interessar-nos genuinamente pela complexidade essencial: a do domínio
  3. Conversar ativamente com os especialistas de domínio
  4. Encontrar formas de romper as barreiras de comunicação, trazendo a linguagem do domínio (o vocabulário do negócio) para dentro do código

Esse objetivo não significa ignorar completamente questões técnicas ou de legado — elas são importantes e precisam ser gerenciadas. Mas significa priorizar o entendimento do problema de negócio acima da sofisticação técnica.

2.7. Quando a Implementação do DDD Dá Errado: O DDD-Lite

A distorção metodológica mais comum na adoção do DDD, conhecida como DDD-Lite, manifesta-se quando a equipe técnica subverte a hierarquia de prioridades, negligenciando a colaboração com os especialistas de domínio.

Ao omitir a etapa de modelagem estratégica e a construção da Linguagem Ubíqua, o foco desloca-se indevidamente para a aplicação mecânica de padrões táticos (VERNON, 2013).

Sintomas do DDD-Lite:

Nesse contexto, observa-se uma ênfase excessiva na implementação de artefatos técnicos como:

  • Entidades (Entities)
  • Objetos de Valor (Value Objects)
  • Repositórios (Repositories)
  • Shared Kernels
  • Agregados (Aggregates)

Tratados muitas vezes como itens obrigatórios de um checklist arquitetural.

Entretanto, tal abordagem contradiz a essência da metodologia. Conforme Evans (2003), esses padrões não constituem o objetivo final do desenvolvimento. Eles são, na verdade, mecanismos expressivos projetados para articular o modelo de domínio dentro do código, e não um objetivo em si mesmo.

A utilização desses padrões de forma dissociada de um entendimento profundo do problema de negócio resulta em uma complexidade acidental elevada, sem entregar o valor estratégico proposto pelo DDD (JUNIOR, 2020).

Ou seja, ao invés de atacar a complexidade no coração do software, acaba-se introduzindo complexidade acidental no desenvolvimento de software.

2.8. O DDD “Anêmico”

Essa priorização da técnica sobre o negócio culmina, frequentemente, na proliferação de Modelos de Domínio Anêmicos.

Segundo Fowler (2003), esta anti-padrão caracteriza-se por objetos que, embora possuam a aparência de objetos de domínio, limitam-se a estruturas de dados desprovidas de comportamento, compostas estritamente por métodos de acesso (getters e setters).

O Paradoxo:

Paradoxalmente, esses modelos costumam estar envoltos em uma arquitetura de alta sofisticação técnica, normalmente repleta de:

  • Repositórios genéricos complexos
  • Múltiplas camadas de abstração
  • Serviços complexos e acoplados

Isso representa o oposto do que o DDD prega. Arquitetura inflada e overengineering é a antítese da filosofia proposta por Evans, uma vez que isso adiciona complexidade acidental sem capturar a riqueza do negócio (VERNON, 2013).

2.9. Conclusão: O Retorno aos Fundamentos

A implementação do Domain-Driven Design exige o reconhecimento de que seu propósito fundamental é o gerenciamento da complexidade essencial, que é a de domínio.

A metodologia não foi pensada como panaceia ou bala de prata para os problemas da solução técnica ou para a gestão do legado. DDD não serve para resolver os problemas da solução técnica ou lidar melhor com o legado.

Quando DDD faz sentido:

Além disso, DDD se encaixa melhor em cenários onde os domínios são complexos. Se o domínio do problema é simples, o DDD agrega pouco valor e pode até mesmo atrapalhar.

Ou seja, em domínios triviais ou de baixa complexidade cognitiva, a adoção de padrões táticos do DDD tende a gerar um custo de implementação injustificável, agregando burocracia em vez de valor (EVANS, 2003; JUNIOR, 2020).

O Objetivo Final:

Devemos sempre nos lembrar do objetivo final do DDD: atacar a complexidade no coração do software, não introduzir complexidade artificial no processo de desenvolvimento de software.

Na próxima seção, exploraremos o mecanismo central para atacar essa complexidade essencial: a Linguagem Ubíqua.



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