Fluxo de análise e desenvolvimento de software - modelo DDD

Percebo que o DDD (Domain-Driven Design) é um assunto cada vez mais procurado por desenvolvedores. Mesmo assim, seu significado pode ser bem confuso para algumas pessoas. Se você nunca ouviu falar, ou já ouviu mas quer ter outra perspectiva, ou ainda fica na dúvida a respeito dos pontos abaixo, esse artigo é pra você.

  • O que é o DDD?
  • DDD é uma arquitetura?
  • DDD é o modelo ideal para se trabalhar?

Boa leitura!

O que é o DDD?

O DDD é uma filosofia de desenvolvimento divulgada por Eric Evans desde 2003. “Divulgada” porque nem tudo foi criação dele. Ele percebeu que um conjunto de boas práticas de desenvolvimento, trabalho em equipe e estratégias de negócio podem contribuir para que um projeto complexo seja bem sucedido.

Livro DDD - Eric Evans

Conhecido pelo seu livro “Domain-Driven Design – Atacando as Complexidades no Coração do Software”, Evans apresenta uma mudança de paradigma tão grande sobre a forma de entender e solucionar problemas complexos, que inspirou diversos outros ótimos livros sobre o assunto.

DDD é uma arquitetura?

Tradicionalmente, aprendemos um modelo de análise e desenvolvimento de software semelhante a este: os analistas de negócio, em conjunto com os especialistas de negócio e/ou usuários-chave, farão um levantamento funcional, e elaborarão um extenso documento de especificação funcional. Talvez aqui tenhamos a participação de um especialista em banco de dados para realizar o MER, e talvez mais alguns documentos e diagramas. Essa especificação será enviada para o arquiteto, ou líderes / responsáveis técnicos, que desenharão a arquitetura do projeto, de forma a atender os requisitos especificados. Outros conceitos bem vistos no mercado, porém que não foram expressamente solicitados, podem ser englobados na arquitetura, como alto nível de abstração e reutilização de código, camada de acesso a dados que permita a troca do SGBD sem impactar o projeto, diversos Patterns e etc. Então, os desenvolvedores colocarão a mão na massa e implementarão os requisitos. O projeto desenvolvido será disponibilizado para os usuários-chave, que irão validá-lo e aprová-lo, conforme mostrado abaixo:

Fluxo de análise e desenvolvimento de software - modelo tradicional

E tudo funciona conforme a especificação, certo? 🙂

Bom, se você se sentiu confortável com essa descrição, e está confiante que esse modelo funcione, talvez o restante do artigo incomode um pouco.

Digo isso porque em boa parte dos dos casos esse modelo não funciona. Entre as razões possíveis, posso citar:

  • A visão do analista de negócios pode não ser técnica o suficiente para entender os riscos, prazos e impactos da solução;
  • O entendimento de um negócio é algo crescente. Dificilmente a primeira versão de uma especificação funcional é a que soluciona adequadamente o problema;
  • O arquiteto, ou responsável técnico, vai desenhar a solução de acordo com a especificação, que pode mudar ao longo do projeto. Ou seja, a arquitetura proposta no início pode não ser a mais adequada no final;
  • O arquiteto ou responsável técnico, se não tiver um contato próximo ao time de desenvolvimento, pode tomar decisões arquiteturais ou de implementação não compatíveis com o time, seja por skills técnicas ou mesmo por estilo de desenvolvimento;
  • Se o arquiteto tem uma visão limitada sobre o problema a solucionar, os desenvolvedores têm em dobro: além da especificação funcional que tende a ficar defasada, estão trabalhando numa arquitetura imposta que não necessariamente soluciona o problema de negócio. Pode resolver problemas que não existem, como a troca de um banco de dados que pode nunca acontecer, e não ser flexível o bastante para o crescimento da aplicação, por exemplo;
  • Os desenvolvedores vão dar o seu melhor para atender o prazo e os requisitos dentro da arquitetura imposta. Porém quando o projeto for disponibilizado aos usuários, talvez meses depois da análise de negócios, os usuários tenham entendido que não era bem isso que eles queriam.

As mudanças serão necessárias para atender as necessidades atuais dos usuários, e não as de meses atrás. Mas os desenvolvedores podem encontrar dificuldades em implementar as mudanças dentro de um padrão imposto. Isso gera complexidade técnica acidental. O código muitas vezes fica mais complexo do que deveria porque precisa seguir certos padrões definidos no início. À medida que o sistema vai crescendo, a complexidade técnica acidental fica maior do que a própria complexidade do negócio.

Complexidade acidental de software

Complexidade de domínio x complexidade do software

Justamente por isso as comparações de desenvolvimento de software com engenharia civil ou eletrônica costumam falhar: O projeto cresce. O entendimento do negócio cresce. As necessidades mudam. E às vezes, mesmo quando a necessidade se mantenha a mesma, pode ser que a noção de qual será a solução adequada muda. Desenvolver software de uma forma que não permita mudanças estruturais durante o desenvolvimento normalmente leva a projetos de baixa qualidade e muitas horas extras.

E o que o DDD tem a ver com isso?

O DDD é uma filosofia voltada ao domínio do negócio. O entendimento do domínio do negócio é um processo crescente, que necessita da cooperação e comunicação da equipe como um todo. Ao invés do modelo tradicional, em que a comunicação ocorre em apenas algumas etapas do projeto, temos um fluxo de comunicação contínua e colaborativa, por meio de uma única linguagem.

Fluxo de análise e desenvolvimento com linguagem ubíqua

Fluxo de análise e desenvolvimento de software - modelo DDD

O código reflete o domínio, na mesma linguagem dos especialistas de negócio e usuários. Termos estritamente técnicos são substituídos por termos que o usuário compreenda. Talvez alguns diagramas possam servir de apoio, mas ao invés de documentos extensos e detalhados, temos um código rico, claro e coeso.

O time de desenvolvimento como um todo se torna responsável pela arquitetura do projeto. O papel do arquiteto pode até continuar a existir, mas numa posição muito mais colaborativa e próxima do dia a dia de desenvolvimento.

A implementação da solução é emergente. Começa simples, e cresce junto com o entendimento do domínio, e não em etapas separadas. Pode ser que em algum momento, perceba-se que a arquitetura não atenda mais. Um conceito chave que impacta na clareza do domínio (código) pode ser percebido, gerando a necessidade de refatoração parcial. E tudo bem se isto acontecer.

Não se investe tempo em padrões e abstrações que não são necessárias. A energia do time, técnico ou não, é direcionada para um único objetivo: solucionar o problema de domínio, de uma forma em que o código reflita o domínio.

Em resumo, mesmo o DDD não sendo um padrão de arquitetura, ele afeta como as decisões arquiteturais são tomadas, e o próprio papel do arquiteto no time.

Parece o máximo, não? Isso nos leva para a próxima pergunta:

DDD é o modelo ideal para se trabalhar?

A resposta é… Depende! Em primeiro lugar, o DDD é um modo de lidar com domínios complexos. Se o domínio em questão for simples, você será mais eficiente usando designs mais simples. Mas mesmo que o domínio seja complexo, outros fatores devem ser considerados:

  • Cultura da empresa: uma empresa que está acostumada com ITIL ou semelhante, com papéis bem definidos e times segregados, terá dificuldades em romper essas barreiras para um modelo colaborativo. Pode ser que, dentro do possível, as coisas estejam indo bem dessa forma, então não há a necessidade de mudar. Mas caso o modelo atual de trabalho esteja impactando as entregas, gerando desgastes, documentação defasada e código de baixa qualidade, entre outros efeitos, talvez os gestores sintam a necessidade de mudança. Se sim, pode ser válido conversar sobre DDD, o que não garante que os gestores se sintam confortáveis com as mudanças propostas. Em outras palavras, as pessoas envolvidas precisam querer e acreditar nessa mudança, a ponto de se comunicarem e colaborarem diretamente com o desenvolvimento do software, e não apenas com a especificação e prazos;
  • Engajamento dos desenvolvedores: Para que o código reflita o domínio, uma série de práticas de desenvolvimento são recomendadas. Existem muitas formas de resolver o mesmo problema, e muitas formas são aceitas, contanto que ao analisar a aplicação, seja possível entender qual o domínio principal, suas regras e peculiaridades, quais os domínios auxiliares, como eles se relacionam, etc. Não basta apenas metade dos desenvolvedores estarem engajados em codificar refletindo o domínio, todos precisam assumir essa responsabilidade.

O DDD é voltado para domínios complexos, e depende da quebra de barreiras de comunicação entre especialistas de negócio e especialistas técnicos, além do engajamento do time técnico em programar de forma que o código reflita o domínio. Se uma dessas variáveis for negativa, provavelmente o DDD não serve para o cenário que você está lidando.

Já está claro que o DDD não é uma arquitetura, nem uma bala de prata que resolverá qualquer problema que vier. Mas caso seu time identifique que o domínio em questão é complexo, e esteja disposto programá-lo de forma que a representação do domínio seja clara até para o especialistas de negócio, e perceba que o cliente ou empresa está interessado em colaborar constantemente com o entendimento do domínio e validação da solução, talvez o DDD seja uma boa abordagem de desenvolvimento.

Como aplicá-lo, então?

Não existe resposta rápida para essa pergunta, então vou dedicar meu próximo artigo para explicar isso. Espero que eu tenha ajudado os leitores a entender o que é o DDD, ou ao menos, o que não é o DDD.

E fica a recomendação de buscar a informação direto da fonte. Caso o livro do Evans seja muito denso (e é mesmo), recomendo começar por outro mais didático e prático: “Patterns, Principles and Practices of Domain-Driven Design”, de Scott Millett e Nick Tune. É uma leitura mais leve e direta, com exemplos de implementação em C#.

Scott Millett & Nick Tune - DDD

Graziella Bonizi