Domain Driven Design - Quando o gavião come a barata?
Enviado em 5 de Setembro de 2008
Publicado por Felipe Rodrigues | Enviar por e-mail
| Hits para esta publicação: 860
Há algum tempo (mais ou menos 4 anos) venho estudando e aplicando Domain Driven Design em diversos projetos. Normalmente meu trabalho nos projetos é planejar e construir a arquitetura dos sistemas ou avaliar e corrigir arquiteturas criadas por outras pessoas. Não precisa nem dizer qual dos dois eu prefiro né?
Para que eu possa expressar melhor o motivo que me levou a especialização em Domain Driven Design preciso voltar ao meu primeiro curso de Orientação a Objetos. Lá estava eu (há 7,5 anos atrás) com experiência em linguagens como C, Pascal, Object Pascal (Delphi), mas sem nenhuma noção do que era um "objeto". Após uma breve explicação dos conceitos, vieram os exemplos de meu professor:
Lê-se: "Gavião é uma Ave que é um Vertebrado que é um Animal" e "Barata é um Inseto que é um Invertebrado que é um Animal".
Quando eu comecei a entender essas relações eu imediatamente comecei a pensar nas diversas interações entre esses objetos. E comecei a pensar em como expressar as situações utilizando esses objetos. Como exemplo, pense na seguinte situação:
"O Gavião normalmente come a Barata."
Uma forma de expressar isso em orientação a objetos seria:
Que resultaria em :
Pronto… código muito simples e de fácil compreensão. Isso não passa de orientação a objetos. O importante é entender a quantidade de práticas envolvidas neste exemplo e que só pude perceber depois que comecei a estudar Domain Driven Design.
O processo
Implementar Domain Driven Design implica modificar a cultura de desenvolvimento de software que hoje está impregnada nas maioria das empresas. Domain Driven Design significa desenhar software de acordo com o domínio (conjunto de informações e situações) relacionado ao problema que o software se propõe a resolver.
Esse domínio deve ser definido já no começo do projeto, pelo menos de forma superficial, para que você saiba o objetivo do software. Depois disso começa o aprofundamento no domínio. É importante lembrar que sua arquitetura e seu ambiente de desenvolvimento deve preparado para evolução, protegido por integração contínua e TDD para garantir a evolução do domain. Práticas de desenvolvimento ágil são muito úteis para isso.
Em algum momento na caminhada iremos começar a desenvolver software e consequentemente trabalhar com o domain, aprofundando o conhecimento da equipe. Existem algumas dicas para obtenção do conhecimento, exploração de conceitos ocultos e implicitos, para garantir que o domain reflita a situação em um nível aceitável.
O fator fundamental é dialogar muito com os domain experts (pessoas que possuem experiência no processo de negócio do qual o domain trata). Sem os domain experts não é possível realizar domain driven design (Alguém ve alguma semelhança com agile?) São eles que vão determinar quais são as informações e situações que o domain deve tratar. Isso exige postura por parte de quem desenvolve, já que a pessoa que desenvolve deve ser a mesma que irá obter o conhecimento.
Voltando ao nosso exemplo, a frase "O Gavião normalmente come a Barata." representa uma explicação ou definição do domain expert e portanto deve fazer parte do domain. Essa situação de negócio pode ser expressada graficamente da seguinte forma:
Esse é um exmplo simples, mas com esse tipo de notação pode-se expressar processos de negócio complexos, o que ajuda muito na visualização do domain. É importante observar que nesta notação bem simples, temos todos os conceitos explicitos. Isso nos dá o gancho para o próximo item que é a criação de uma linguagem comum para o time.
Ubiquitous Language
Um importante conceito do Domain Driven Design é a criação e manutenção de uma linguagem comum, tanto para o cliente quanto para o time de desenvolvimento. A premissa diz que ambos devem expressar o negócio da mesma forma e isso visa melhorar a comunicação e o entendimento entre as partes.
Essa linguagem comum deve estar presente no dia-a-dia da equipe incluindo a obrigação de ser expressada em documentos e no código também. No nosso exemplo o código expressa exatamente o conceito antes comunicado pelo Domain Expert (a frase "O Gavião normalmente come a Barata." ), comunicada pelo diagrama:
Isso é conseguido através de algumas técnicas de Supple Design (um dos mais interessantes conceitos de Domain Driven Design) e é facilitado com a aplicação da técnica de Fluent Interface.
Refactoring
Pensando na situação do exemplo, "O Gavião normalmente come a Barata" nos deixa com muitas dúvidas sobre esse contexto. De onde veio a barata? De onde veio o gavião? O que acontece quando o gavião come a barata? O que o domain expert quer dizer com "normalmente"? Onde está o wally?
Podemos aprofundar nosso conhecimento a partir do momento que o domain expert responder essas perguntas. Mas essas perguntas podem gerar novas perguntas e consequentemente, mais conhecimento a ser expressado. Continuando no exemplo:
Pergunta de desenvolvedor:
- Por que você (o domain expert) diz com "O Gavião NORMALMNETE come a Barata"? O que quer dizer "normalmente"?
Resposta do Domain Expert:
- O Gavião normalmente come a barata, mas tem vezes em que a barata consegue escapar do gavião.
Pergunta de desenvolvedor:
- Então a barata luta para não ser comida?
Resposta do Domain Expert:
- Sim. A barata tenta se esconder na hora em que o gavião começa a sobrevoa-la. Se a barata escapa então o gavião procura outra presa. Se a barata não consegue então o gavião come a barata. Mas isso é tão obvio que eu nem falei antes.
Nesse momento nosso conhecimento sobre o processo de negócio é mais profundo. Isso exige um refactoring em nossa ubiquitous language. Devemos modificar os documentos, a forma de falar, os diagramas e o código. Vejamos como ficaria nesse caso:
Nesse pequeno exemplo pudemos identificar a variação entre um conceito solto do processo e um pequeno detalhe "óbvio" que o domain expert não mencionou porque era obvio. Quantos problemas você já enfrentou porque deixou passar algum "detalhe óbvio"? Agora que temos o processo de negócio refatorado podemos partir para a implementação do código:
Percebam que na hora de implementar o código, vários detalhes aparecem (as ações gaviao.comeu?() e gaviao.caçar()). Por isso é fundamental que o dialogo com os domain experts sejam constantes. O conhecimento evolui e nossa imaginação pode dar direções diferentes para uma situação, por isso validar o conhecimento com o domain expert é muito importante. Além disso podemos melhorar a implementação desse código (técnicamente falando) de várias formas. Talvez o do…while não seja a melhor opção para expressar este caso. Isso deve sempre ser realizado em inspeções de código, trazendo uma visão de fora para verificar a clareza e eficiência do código. Alguém se dispõe a otimizar esse algorítimo?
Conclusão
Praticar Domain Driven Design é algo deve ser feito em equipe, com foco em negócio e nas situações do ponto de vista dos domain experts. O DDD foca em expressar negócio em forma de software para que possamos minimizar complexidade desnecessária e consequentemente custos de produção e manutenção. A orientação a objetos, apesar de um conceito isolado ao DDD, vem para ajudar na implementação de um bom design orientado a domínio. O DDD por outro lado oferece um processo que facilita muito a aplicação de Orientação a Objetos na forma mais pura e por isso eu costumo dizer que Domain Driven Design oferece a nós desenvolvedores um caminho de volta à orientação a objetos. Confiram em breve mais artigos sobre DDD e sua práticas aqui no blog.
Tenho estudado DDD e também aplicado nos projetos que trabalho, estou gostando muito do resultado!
Ah, um errinho que encontrei, está trocado de posição os textos em vermelho (”não consegue” e “consegue”) não?
Abraços,
Tiago Soczek
Você estava certo Tiago. Eu já corrigi a posição dos textos em vermelho. =)
Valeu pela força.
Ótimo post.
Nossa equipe está aplicando DDD no dia-a-dia o desenvolvimento de nossas soluções, mas é dificil…
Algumas coisas tem nos brecado momentaneamente, como por exemplo complexidade prematura, mas estamos corrigindo isso.
Aliás o contato direto com nossos Domain Expert’s é que tem nos dados um ganho terrível nesse sentido.
Aplicar DDD corretamente não é fácil não.
Li alguns textos por aí que diziam para começar aos poucos, ou seja, aplicar DDD em partes…
Não tenho uma opinião formada quanto à isso, mas acho que ou faz de forma correta (100%) ou não faz nada.
Felipe, qual sua opinião quanto à isso?
Fábio,
Concordo com o que você falou, aplicar DDD corretamente nào é fácil. Depende de uma mudança cultural na empresa, similar à mudança exigida pelos processos ágeis. A presença do cliente, o foco no que é importante pro cliente, o desenvolvimento evolutivo, etc. Tudo isso pode ser resolvido com a implantação de uma metodologia ágil, porém DDD é independente disso.
Eu não vejo como começar aos poucos. Eu vejo o seguinte: DDD é um conjunto de práticas que formam um processo de design de software. Essas práticas juntas oferecem 100% dos benefícios de DDD. Aplicar parte dessas práticas pode trazer uma quantidade menor de benefícios, mas ainda assim trará benefícios. Dessa forma, acredito em níveis de ganho e trade-off. Mas dizer que faz DDD já exige um pouco mais de perícia.
Isso daria um artigo por si só (vou tentar conseguir tempo pra postar sobre isso).
Abração
Estou torcendo pela barata, esperando que o Gavião reveja seu cardápio, e se torne vegetariano, pois é mais saudável. Bobagem, o equilíbrio da natureza se encarregaria de achar inimigos naturais para evitar que algo se torne desequilibrado.
Gostei do enfoque parcialmente funcional e parcialmente declarativo, passando pelo procedural com ligeiros toques cognitivos com o ensejo operacional de uma base de conhecimentos relacional. Faltou linguagem de máquina, podendo ser uma virtual ou um micro-programa.
Muito bom Felipe. Parabéns!
Ótimo exemplo, bem esclarecedor.
Post muito bom Felipe.
Algo como DDD in a nutshell.
[]’s
Pedro
Parabéns pelo Ótimo post !! Bastante claro, simples e objetivo.
Parabéns Felipe!
Muito claro nas suas colocações, direto, sem muitos floreamentos.
Também fiquei contente em perceber que utilizo há tempos DDD sem perceber.
Outro item que concordo com você que o DDD traz de volta a Orientação a Objetos. Fui no JustJava semana passada e o que muito se falou foi simplicidade. Será que o DDD não é o mais básico? Será que não é por isso mesmo que ele é tão bom?
Parabéns novamente e ficarei aguardando outro post.
Olá Felipe !!!
Parabéns pelo post, foi muito esclarecedor, já venho estudando DDD algum tempo e este post veio bem a calhar !!
E posta mais aí para a gente =)
Abraço
Felipe, vocês pensam em traduzir o DDD Quickly?
Sim Joel…
Pretendemos traduzir este e também os outros livros. O problema é que precisamos de voluntários para nos ajudar nas traduções para que o processo seja mais rápido. Caso contrário pode demorar um pouco.
Quero te parabenizar pelo post, muito legal.
É muito importante esclarecer que o óbvio, as vezes, não é tão óbvio. Ainda mais em se tratando de conversas entre desenvolvedores e “domain experts”. O que é mais difícil em DDD é chegar na “Ubiquitous Language”. Um dia agente chega lá.
Abs