Conhecimento nunca é demais não é mesmo? Ainda mais quando o assunto é Domain-Driven Design (DDD), que se destaca por reunir boas práticas de design estratégico e design tático, apoiando todo o ciclo de desenvolvimento de software e possibilitando criar sistemas de alta complexidade.
Quem nunca recebeu uma pergunta matadora em um processo seletivo? Quando vamos responder, tentamos reunir diversas informações, abrindo um leque de tópicos sobre o assunto para consolidar um argumento conciso sobre o tema.
Podemos dizer que questionamentos como “O que é Domain-Driven Design?” ou “Como você aplicaria Domain-Driven Design?“, devem ser consideradas como perguntas desta magnitude.
Principalmente, devido a tamanha dificuldade de se chegar a uma boa definição de um conceito extremamente denso como esse, que nos impede de responder essa pergunta de pronto e com total convicção.
Tenho a intenção nesse artigo de criar uma base sobre o assunto, de forma a encaixar os seus principais pontos, como um primeiro passo nos estudos do DDD.
Afinal, o que é Domain-Driven Design?
O Domain-Driven Design, também conhecido pela sigla DDD, fornece uma estrutura para tomada de decisões, combinando práticas de design e desenvolvimento de software.
Centrada na lógica de negócios, ou domínio, sua ideia básica propõe, por meio de uma coleção de padrões e princípios de design, auxiliar todo o ciclo do desenvolvimento,para construir aplicações que reflitam o real entendimento dos processos e regras do negócio.
O DDD está além da forma de pensar, desenhar e desenvolver o software, mesmo não sendo um padrão arquitetural, afeta em como as decisões de construir um software são tomadas.
Voltando à história, a origem do termo surgiu com o livro escrito por Eric Evans, em 2003. Desde então, uma comunidade de profissionais desenvolveu ainda mais os princípios, gerando outras importantes obras.
Evans identificou e catalogou em seu livro os principais elementos conceituais, com foco na ideia de que para desenvolver softwares com um domínio complexo, precisaríamos construir uma linguagem ubíqua, ou seja, onipresente.
Principais pílulas de conhecimento do DDD
Na literatura de TI, temos ótimos livros a serem explorados sobre DDD, porém neste primeiro momento irei destacar dois deles:
– “The Blue Book”: escrito por Eric Evans, em 2003, com o título “Domain-Driven Design: Atacando as complexidades no coração do software”;
– “The Red Book”: escrito dez anos mais tarde, em 2013, por Vaughn Vernon, sob o título “Implementando Domain-Driven Design”.
Como disse antes, temos em mãos um assunto bastante denso, onde somando o rico conteúdo dos dois livros são mais de mil páginas de informações, para quem tem interesse em se aprofundar no assunto.
Vamos ver se você entende a referência: a fonte canônica do DDD, escrita por Eric Evans, é representada pela pílula azul; e, o livro de Vaughn Vernon, que assim como a cor de sua capa, representa a pílula vermelha. Qual se deve escolher?
Por mais que o livro de Evans não seja uma das leituras mais fáceis na literatura de software, ainda assim possui um conteúdo substancial e de extrema riqueza para toda a comunidade.
Desta forma, a união com o conteúdo escrito por Vernon é perfeita. Sendo que esta tem como foco principal a implementação prática do DDD, trazendo consigo uma ótima representatividade sobre o design estratégico.
Com isso, concluo que os livros são complementares e que, neste caso, o ideal seria provar as duas pílulas.
Diferente do que acontece em The Matrix. ?
Domain-Driven Design – Décadas de conhecimento
Muita gente acredita que o DDD é um conceito moderno, uma ideia nova recém-descoberta. Na verdade, ele nasceu entre os anos 50 e 60 com o surgimento dos primeiros conceitos orientados a objetos, criados para solucionar problemas muito complexos, no qual uma abordagem procedimental não era suficiente.
No final da década de 60, surge o que muitas pessoas consideram ser a primeira linguagem orientada objeto (OOP, sigla em inglês para Object-Oriented Programming), o Simula 67, que apresentava um resumo de todos os conceitos e experiências reunidos até o momento naquela direção.
Anos mais tarde, em 1982, surge um novo estágio evolutivo da OOP, porém dessa vez unindo o resultado da experiência adquirida com os anos de uso do Simula 67 e de outras Linguagens Orientadas a Objeto, com o conteúdo de novos White Papers, gerando a Análise e Design Orientado a Objetos (também conhecido como OOAD, sigla em inglês para object-oriented analysis and design).
Em 2003, surge um novo marco, com o livro escrito por Eric Evans, declarando a comunidade um novo termo: DDD. Na obra, é apresentada as melhores práticas e novos conceitos com base em anos de experiências reunidas, gerando uma estruturação evolucionária do OOAD.
Resumindo toda a experiência coletada nos próximos 10 anos após a publicação do livro de Evans, em 2013, Vaughn Vernon define o próximo estágio da evolução do DDD.
Podemos considerar que o conteúdo aqui explicado tem pelo menos 50 anos de sabedoria e experiência da comunidade de desenvolvedores de software, sobre como lidar com domínios de problemas complexos.
Entendendo o Domain do Driven Design
Para definir o Domain-Driven Design, primeiro precisamos consolidar nosso entendimento sobre o Domain ou Domínio, em português. O termo é de extrema relevância, visto que o nosso design passa a ser orientado por esta palavra-chave, que representa simplesmente a razão do software existir.
A necessidade de um software ser construído está relacionada a um contexto delimitado de ideias, conhecimentos, processos e problemas que se deseja resolver, no qual uma empresa está inserida.
Trazendo para o mundo real, o domínio de nosso projeto será formado por todo conhecimento absorvido sobre a empresa, assim como o modelo que ela opera.
Isso significa observar o envolvimento de regras de negócio, processos e possíveis integrações com sistemas existentes como parte da solução, sejam eles internos, de parceiros ou fornecedores.
Portanto, o Domínio representa o coração do negócio em que estamos trabalhando, com todas as suas regras e peculiaridades que o DDD visa atacar, conforme está explícito no título do livro de Evans: “Atacando as complexidades no coração do software”.
DDD – Atacando as complexidades do software
Adquirimos a habilidade de lidar com a complexidade do software, em grande parte tentando e eventualmente falhando, sendo que até mesmo com pouca vivência na área de desenvolvimento de software, percebemos que nem tudo sai conforme o planejado.
Muitas vezes, paralelo à construção do software, surgem novas necessidades, assim como aparecem pontos cegos no entendimento de um negócio, que não enxergávamos no começo do projeto.
Principalmente para softwares complexos, temos dificuldades de solucionar o problema adequadamente, baseado na primeira versão de especificação funcional, o que dificulta sermos assertivos na melhor arquitetura a ser utilizada.
Os fatores acima, às vezes aliados à falta de engenharia bem definida ou até mesmo ao excesso de engenharia (Software Overengineering), dificultam o atendimento de mudanças impostas por novas necessidades do negócio, gerando desta forma complexidade técnica acidental.
Conforme imagem acima, a complexidade do software resulta da complexidade do domínio/negócio, multiplicado pela complexidade técnica acidental.
Em suma, o gráfico nos mostra que conforme o sistema cresce, a complexidade técnica acidental se torna maior que a complexidade do negócio, dificultando desta forma a manutenção e a sua evolução, problema conhecido no DDD como Big Ball of Mud.
Design estratégico x Design tático
O DDD nos apresenta dois tipos de ferramentas de design.
A primeira delas nos ajuda a resolver problemas relacionados à modelagem de software, o design estratégico.
Enquanto o design tático, que ocorre após a fase estratégica, se concentra no desenvolvimento do produto, focado nos detalhes de implementação.
O design estratégico agrupa um conjunto de princípios e padrões, para dividir um problema complexo de negócio em vários blocos com limites claros e responsabilidades específicas, construindo desta forma uma topologia de design de software de alto nível.
Já o design tático, por sua vez, possui um conjunto de padrões de abstração de componentes de nível médio e baixo do software. Com seus padrões práticos, o tático refina o resultado do design estratégico aplicado, convertendo-o em código.
O Domain-Driven Design é um processo em evolução que consiste em ciclos iterativos de aplicação de design estratégico e tático. Você começa com o design estratégico, seguido pelo design tático.
Pessoas desenvolvedoras atuam com as ferramentas de design tático, mas se tivermos conhecimento e uma boa compreensão das ferramentas de design estratégico, isso nos ajudará a arquitetar um software melhor.
Design estratégico ou modelagem estratégica
Agora que a gente já entendeu as diferenças e a relação entre design estratégico e design tático precisamos nos debruçar no design estratégico, também chamado de modelagem estratégica.
O design estratégico é um dos pilares do DDD que tem como principal objetivo definir os Bounded Contexts, a Linguagem Ubíqua e os Context Maps. Tudo com a colaboração de toda a equipe do projeto, composto pela equipe técnica e os especialistas do domínio ou Domain Expert.
Para entendermos claramente o design estratégico, precisamos entender melhor cada um desses conceitos relatados acima, formando uma base conceitual para começar a trabalhar com DDD.
Domain Expert, quem conhece o negócio
Agora, com um melhor entendimento sobre o Domain, é essencial entender o papel de um Domain Expert.
É essa pessoa que, com todo o seu conhecimento sobre as necessidades do negócio, apoia o time de desenvolvimento de software na modelagem do domínio, descrevendo o que o sistema deve fazer, com o objetivo de que o código escrito pelo time realmente expresse o negócio.
Para construir um bom software, se faz necessário um excelente conhecimento prévio sobre o negócio. Não seria razoável criar um software complexo, sem nunca ter tido contato com aquele segmento, certo?
Vejamos o exemplo de um sistema de análise de contas médicas:
O sistema seria criado para uma empresa de planos de saúde, onde identificariam objetos de domínio, tais como remessas, lotes, guias e procedimentos médicos. Temos também as regras que regem o negócio, como: “O valor da Guia Médica deve ser igual à soma dos itens” ou “Um lote só pode ser fechado após análise, quando todas as Guias Médicas estiverem concluídas e analisadas”. Assim como podemos ter análises mais complexas, como “Procedimentos pediátricos não podem ser pagos quando realizados em adultos” ou “Procedimentos de alto custo não devem ser pagos se não autorizados pelo plano de saúde”.
Ao desenvolvermos precisamos obter o conhecimento do domínio, que pode ser extraído de documentações ou manuais de procedimento de negócios, porém certamente perguntas mais complexas surgiram, visando ser mais assertivos, precisaremos de especialistas naquele domínio.
Voltando no exemplo da análise de contas médicas, a pessoa Domain Expert provavelmente seria um analista de contas médicas, com vasto conhecimento e autoridade no assunto, que se tornaria no futuro um usuário-chave do sistema.
Mas teremos casos onde Expert nunca usará o sistema, como profissionais de engenharia de produção que conhecem todo o processo da linha de produção, enquanto os futuros usuários do sistema serão os operadores, ou seja, nem todo usuário será uma pessoa Domain Expert.
Não podemos nos esquecer que para alguns casos, será necessário mais Domain Experts para cobrir todas as frentes que aquele sistema abrange. Por exemplo, um ERP (Enterprise Resource Planning) precisaria de um especialista por domínio.
Afinal, o que é Linguagem Ubíqua?
As pessoas desenvolvedoras, com seu viés técnico, pensam em como transformar a necessidade do negócio em objetos, relacionamentos entre eles, aplicar abstração, herança, polimorfismo, patterns, frameworks, entre outros.
Domains Experts, por sua vez, conhecem a fundo o negócio, porém desconhecem essas terminologias.
Levando em consideração que o software não lida bem com ambiguidades, a Linguagem Ubíqua entra em cena construindo uma linguagem comum, compartilhada entre toda a equipe, indiferente do seu papel no projeto. A fim de reduzir o enigma exposto pelo James Shore no texto abaixo.
“É um enigma. As pessoas que são especialistas no domínio – os especialistas de domínio – raramente estão qualificadas para escrever software. As pessoas que estão qualificadas para escrever software – os programadores – nem sempre entendem o domínio-problema.”
James Shore.The Art of Agile Development, página 126. Tradução livre do autor.
Ao aplicá-la, traduzimos termos técnicos em expressões compreensíveis a todo mundo envolvido, o mesmo ocorre para as terminologias utilizadas pelo negócio, gerando uma intersecção entre as partes.
Este trabalho em conjunto gera um curto ciclo de feedback, fortalecendo os laços entre especialistas do negócio e o time de desenvolvimento, produzindo desta forma um software que faz mais sentido para o negócio.
Bounded Context
Ao lidarmos com grandes domínios, no decorrer de sua modelagem se torna complexa a construção de um modelo unificado. Visto que cada área de negócio usará um vocabulário sutilmente diferente com base no contexto que vivencia em seu dia a dia, geralmente levando a muita confusão.
Uma das principais ferramentas contidas no design estratégico, o Bounded Context ou Contexto Delimitado, nos apoia a lidar com grandes modelos de domínio, estabelecendo limites ao dividi-los em contextos menores, criando inter-relacionamento explícito entre eles.
Dentro destes limites conceituais, todos os termos e frases têm um significado específico refletindo a linguagem ubíqua, guiando o time a entender melhor o negócio e sinalizando até onde vai a responsabilidade de cada parte do sistema.
Afinal, a fronteira entre contextos deve ser clara para todos. Além de cada contexto poder ter sua própria linguagem ubíqua, o mesmo é válido para a arquitetura do software.
Context Map
Context Map ou Mapa de Contexto nos apresenta uma visão global do software, uma forma pragmática de gerar um documento, um rascunho, uma imagem, ou um esboço que facilite o entendimento dos contextos da aplicação. Não precisa ser nada complicado, sendo uma boa opção desenhar a mão com o uso de um quadro branco, por exemplo.
Inicialmente, desenhe um Mapa de Contexto visual da situação atual do projeto, um diagrama simples que captura o terreno existente, ele será o esboço inicial do nosso mapa. Mapeando o presente, não o futuro imaginado. Afinal, precisamos ter uma forte compreensão de onde estamos, antes mesmo de saber para onde gostaríamos de seguir.
Por não ser um documento oficial, deve ser simples, de alto nível e informal. Não se limitando a um diagrama arquitetural do sistema, mas sim abrangendo a compreensão das relações entre os contextos delimitados da corporação.
O mapa vai ajudar a equipe do projeto a entender o domínio do negócio, as fronteiras entre os contextos ou como elas podem ser integradas. Conforme o projeto avança, o diagrama deve ser atualizado, seguindo os novos cenários propostos.
Fazendo uma analogia: podemos imaginar o continente da América do Sul, com base na sua colonização, representando nosso domínio. Conforme imagem abaixo, devido ser um mapa moderno, algumas regiões foram extrapoladas pelo exemplo.
A região foi colonizada por cerca de cinco países distintos, a divisão entre eles formaria nossos contextos limitados, através de fronteiras. Cada país teria seu próprio idioma onipresente, onde as leis ou regras que regem cada nação seriam o modelo de domínio. As regras estabelecidas nas fronteiras entre os países e os tratados sobre comércio entre as partes, seriam nossas integrações.
Design Tático
O Design Tático agrupa um conjunto de ferramentas a serem utilizados na construção do seu modelo de domínio, aplicados em um único contexto delimitado, refinando o resultado do trabalho realizado através das ferramentas de Design Estratégico.
Quando utilizados corretamente os padrões de Design Tático, você pode enriquecer seu modelo de domínio (Domain Models), o que consequentemente refletirá o negócio com maior clareza no software desenvolvido. Conforme imagem abaixo, o Design Tático pode ser dividido em dois grupos.
Por se complementarem, ter um conhecimento profundo do Design Tático é tão importante quanto do Design Estratégico no DDD.
Domain Models
Domain Models ou Modelo de domínio mantém o conhecimento estruturado do problema a ser resolvido com o software, representando o vocabulário e conceitos-chave do domínio, identificando os relacionamentos entre todas as entidades, atuando como uma ferramenta de comunicação, em conjunto com a linguagem ubíqua.
Deve representar claramente o problema que está sendo resolvido, assim como a solução proposta. Também pode ser expresso através de um diagrama, ou até mesmo uma documentação escrita, desde que seja acessível e compreensível por todo mundo que tem envolvimento no projeto.
Domain Service
Domain Services ou Serviços de Domínio representa uma estrutura sem estado que fornece comportamentos do mundo real dos negócios, por ser uma extensão do domínio, atua com fluxos de diversas entidades e agregações. Por ser relevante apenas para a lógica de negócios, não deve entrar em contato com detalhes técnicos.
De forma simples, podemos entender que absorve responsabilidades do Domain que o Model não poderia realizar.
Como o modelo de domínio geralmente lida com comportamentos mais refinados, que focalizam alguns aspectos específicos do negócio, um serviço de domínio tende a seguir os mesmos princípios, fornecendo soluções para contextos de negócios que são muito complexos para serem armazenados em uma única Entidade ou Objeto de Valor.
O Serviço de Domínio não tem nenhuma semelhança com os Serviços de outras camadas, exceto o nome.
Camada Anticorrupção
Temos um conceito do DDD que tem ficado cada vez mais em evidência, principalmente devido ao alto uso dos microsserviços (microservices) nos últimos tempos, Anti Corruption Layer ou Camada Anticorrupção, em português.
A Camada Anticorrupção, acaba sendo um valioso mecanismo na proteção do domínio contra conceitos que não fazem parte do seu contexto, garantindo inclusive que o design da sua aplicação não seja corrompido por dependência de microsserviços ou sistemas externos a ele, reduzindo o acoplamento de forma que o sistema possa evoluir independente.
Em resumo a camada anticorrupção pode ser considerada um intermediador que de maneira isolada permite apenas a troca de dados que sejam válidos entre os dois sistemas, prevenindo que não dependam do design um do outro.
Alavancas do Domain-Driven Design
Penso que uma das principais vantagens do Domain-Driven Design, está relacionado a um pilar importantíssimo em qualquer projeto: a comunicação. Enfatizando estabelecer desde o início uma linguagem comum e ubíqua relacionada ao modelo de domínio do projeto.
Assim facilitando o uso de termos da área de negócio, reduzindo o uso de jargão técnico ao discutir aspectos do aplicativo, visto que equipes de desenvolvimento usam a mesma linguagem que especialistas de domínio, resultado em um design de software que faz mais sentido para o usuário final.
Temos um alinhamento mais preciso, pois a pessoa desenvolvedora tem melhor comunicação e compreensão ao falar com a equipe de negócios usando a mesma linguagem, reduzindo o risco de possíveis confusões ou mal-entendidos.
As definições de contexto e limites tornam o software mais flexível à mudanças, pois as divisões geradas pelas separações das responsabilidades, unido com a forte base do DDD em conceitos de análise e design orientado a objetos, sugere que quase tudo dentro do modelo de domínio será baseado em um objeto.
Portanto será bastante modular e encapsulado, diminuindo impactos ao realizarmos mudanças. Além de estabelecer boas práticas, fomentando o uso de padrões de design, obtendo desta forma gerando um código mais limpo e confiável, protegendo o conhecimento do domínio.
Desafios do Domain-Driven Design
O Domain-Driven Design oferece diversas vantagens, mas não necessariamente funcionará para todas as situações.
Por incentivar práticas iterativas recorrentes, o que seria uma vantagem para alguns cenários, esse quadro se distorce. Pois as organizações, muitas vezes, estão altamente ligadas a modelos de desenvolvimento menos flexíveis, como o modelo em cascata, por exemplo.
Embora seja ótimo na construção de softwares onde a lógica de negócios seja bastante complexa, pode não funcionar bem em projetos altamente técnicos, podendo ser desafiador o seu entendimento para profissionais Domain Experts e causando problemas no futuro, caso os requisitos ou limitações técnicas não forem totalmente compreendidos por todo mundo na equipe.
Citei algumas vezes neste artigo sobre o foco do DDD em domínios complexos, porque se o domínio for relativamente simples pode ser muito demorado implementar o projeto, não havendo a necessidade de separações por contextos. Com isso, caímos em outro ponto importante: se você não precisa de uma pessoa especialista em domínio dedicado, provavelmente não precisa do DDD.
Quer saber mais sobre Domain-Driven Design? Então assista a essa live em nosso canal no YouTube:
Conclusão sobre Domain-Driven Design
Importante entendermos que o DDD vai muito além do código, ele torna a equipe mais colaborativa e focada no que mais importa, gerando facilidades ao atender os complexos processos de negócio.
Vantagens como uma efetiva comunicação entre especialistas de negócio e especialistas técnicos, tornando mais eficiente a interação entre os diversos papéis das pessoas que integram o processo de desenvolvimento de software, de forma que o código desenvolvido reflita o máximo possível o domínio.
Não se trata de uma bala de prata, altamente eficaz na resolução de todos os problemas de software.
Assim como qualquer arquitetura de software, metodologia ágil, framework, componente ou ferramenta, temos as suas vantagens e desvantagens, onde nos requer conhecimento e análise para cada cenário, para entendermos se sua aplicabilidade realmente funciona.
Espero ter te inspirado a se aprofundar no assunto. Inclusive, devido ao seu conteúdo extremamente denso, sugiro que, antes de iniciar um projeto utilizando Domain-Driven Design, continue estudando e ampliando seus conhecimentos nos tópicos abordados neste artigo. Seja realizando a leitura de livros sobre o assunto, tais como os recomendados acima, seja assistindo vídeos e até mesmo participando de cursos específicos, se possível.
Referências
- BoundedContext
- Domain-Driven Design Community
- Domain Driven Design (DDD)
- Domain Driven Design: 50 Years Wisdom of Mankind
- Domain-Driven Design: Tackling Complexity in the Heart of Software | Amazon.com.br
- Domain-Driven Design: What is it and how do you use it?
- Implementing Domain-Driven Design | Amazon.com.br
- The Art of Agile Development – Capa comum
- What is Domain-Driven Design?
- What is Strategic Design?
- What is Tactical Design ? – DDD – The Domain Driven Design
- What is the Domain Model in Domain Driven Design?