Serviços de Domínio (Domain Services) | DDD do jeito certo | Parte 11
Вставка
- Опубліковано 6 лют 2025
- Serviços de domínio viabilizam a implementação de operações complexas que não "cabem" em entidades e VOs. Por outro lado, usados de forma inadequada, podem gerar "anemia" no modelo.
Nesse vídeo tentamos explicar o conceito apontando quando e como usar.
----------------
Conheça o grupo intensivo DDD do jeito certo com Elemar Júnior - Grupo intensivo de estudos que conta com MasterClass ao vivo, que vão além da teoria, pois falamos de aspectos práticos, trazendo vivências e exemplos da vida real, baseados em anos de carreira.
exco.me/ddd
Livro Digital
DDD do jeito certo - ddd-do-jeito-c...
professor, cria uma aplicação mostrando todos os conceitos da prática.
esse é o maior problema, ddd sempre é teórico, uma porrada de livros, cursos, vídeos, lives mas sempre teoria
Fantástico como sempre Elemar!
Já trabalhei com pessoas tão puritanas que não aceitavam criar uma SP pra fazer um update que não continha lógica alguma, era só um update..where. E a solução pra isso foi trazer tudo pra memória, fazer o que tinha que ser feito e chamar o UoW.SaveChanges();
Pra mim aquilo era um absurdo tão grande e não fazia sentido algum. Muitas vezes o pessoal esquece que Store Procedure é código também, do lado do banco mas é código e está ali pra te ajudar a fazer alguma coisa de uma forma melhor. Claro que pra mim, quando tem regra de negócios dentro de SPs aí já cheira a gambiarra, mas se é um simples update não tem porque não fazer.
Abraço e continue com a série, está sensacional!
Me desculpe perguntar, mas, por quê você queria fazer uma stored procedure para fazer um update (que me pareceu ser um "update simples") ao invés de usar seu ORM ou só fazer query?
@@fdscbr como foi falado, tem coisas que não valem a pena e são muito custosas quando são feitas de forma puritana, o puritano nesse sentido é não utilizar uma feature nativa de um banco de dados que é uma Stored Procedure pra fazer do "jeito certo". Sendo que, tudo seria resolvido facilmente com uma SP. Então, relativo ao que eu comentei foi em alusão ao exemplo do Elemar, onde que, pra fazer um ajuste simples, onde numa SP tu só teria um update..where, mais nada, agora tu está trazendo tudo pra memória, atualizando e fazendo um commit. Entende que isso não faz sentido nenhum e só adiciona complexidade?( Vai ter que buscar todas entradas onde categoria = alguma coisa, aí vai ter que iterar nisso pra atualizar a propriedade do preço (se for do jeito certo mesmo tu não teria acesso a um set do preço tão facilmente, e aí sim, fazer um SaveChanges). Lembrando, isso não é pra todas as coisas do dia a dia, são pra coisas triviais onde tu precisaria adicionar uma complexidade grande pra fazer alguma coisa de forma simples de uma maneira mais "braçal".
Olha não conto mais as quantidades de pauladas que levei em propor essas soluções "hibridas", onde claramente uma rotina computacional seria melhor performada por uma rotina que "fugiria" a beleza do código. Por exemplo: Usar uma procedure. Inclusive já trabalhei em locais que a palavra procedure não podia nem ser falada entre os devs pois seria inquirido à fogueira.
Obrigado professor. Ajudou o Dev Júnior aqui com as dúvidas. Só agradeço!
As frases que você destacou foram sensacionais.
"Muitos Domain Services = Bad Smell!"
Code Smells tb daria um video a parte, alias uma playlist, a um tempo atrás estudei a fundo o tema e tem bastante assunto pra debater.
"Stored Procedures são código!"
Use quando fizer sentido, principalmente no desempenho.
"Application Services não possuem regras de negócio"
As vezes se torna difícil saber se algumas etapas não estariam explicitando regras de negocio, principalmente quando envolvem vários itens de domínio para chegar a algum ponto, mas ai estaríamos pecando na modelagem.
Serviços de domínio e serviços de aplicação com toda certeza merecem um vídeo a parte!
Obrigado por compartilhar conhecimento e levantar questões com a gente!
Abraços!
Sensacional! Podemos partir do princípio que Serviços de aplicação não deveriam carregar lógica de negócio. Por outro lado, os serviços de domínios carregam e estes têm suas interfaces/contratos definidos na camada de Domain enquanto que suas implementações estão na camada de Infra. Acredito ter entendido.
Então quer dizer que se eu vou apenas manipular mais de um agregado, mas não vou aplicar lógica de negócio em cima, então devo usar serviço de aplicação, mesmo que haja verificações de nulidade em um agregado ou outro retornado.
Estou falando isso, porque num projeto estou trabalhando, eu tenho dois agregados e dentro de um action controller/POST (nacamada de application) onde vou criar entidades e persistí-las, eu acabo fazendo várias verificações nos dois agregados para saber se existe/se é nulo. Caso seja nulo, então crio e persisto.
Para a persistência, estou usando Unit Of Work injetado na controller via construtor.
Após esse vídeo, eu consigo pensar em um design, no qual usaria um serviço de aplicação (com o Unit Of Work injetado via construtor), visto que só faço verificações por nulidade e não aplico nenhuma lógica de negócio em cima.
Por fim, injetado esse serviço na controller (camada de aplicação) e usaria.
Não sei se errei em alguma coisa, mas enfim, valeu o aprendizado. Se alguém pensa diferente, estou pronto para ouvir.
Excelente vídeo. Admiro a didática fantástica desse professor.
Muito bommmm
Video incrivel.
Parabéns pela iniciativa de liberar esse tipo de conteudo de forma organizada e didatica.
Uma duvida sobre Domain Services, eles seriam o mesmo que, algumas outras fontes chamam de 'Use Cases'?
E quanto aos serviços externos, por exemplo se eu for criar um serviço de consulta de cep, onde eu devo colocar a interface e onde eu devo colocar a implementação da interface?
Thiago, imagina que consultar o CEP seja uma regra do seu negócio, então a interface fica no seu domínio mas a implementação (conectar com correios, viacep, etc) ficaria na INFRA pois a implementação não agrega valor intelectual a seu negócio.
Como eu disse na live quando te conheci: o problema é que as pessoas não aprendem modelagem relacional de dados de forma correta. Elas modelam o banco de forma errada.
Costumo deixar somente as interfaces para o domain service, vo e specification. Agora no caso das entidades também faz sentido criar uma interface e mover a implementação para a camada de infra?
Mas se determinado processamento em lote por questões de performance forem feitos em store procedures e esse processamento possuí um complexidade com regras de negócios eu estaria implementando regras do meu domínio na camada de infra. Isso pode ocorrer?
Excelente vídeo. A construção de uma entidade que deve validar os dados de entrada contra a base de dados pode ser feita por um domain service? Exemplo: ao cadastrar um empresa no sistema, eu devo validar se o CNPJ está em uma blacklist.
Provavelmente, sim. Entretanto, provavelmente, você tem essa “verificação” descrita como processo. Garanta que esse processo esteja representado.
@@elemarjr obrigado Elemar
Salve Elemar.
Excelente vídeo. Saudade dos tempos do DNAD lá no centro de São Paulo. Foi quando comecei a prestar mais atenção ao tema de arquitetura de software.
Fez todo sentido a diferenciação entre serviço de domínio e serviço de aplicação, de forma que se eu quiser entender como determinada aplicação funciona, é no serviço de aplicação que estarão minhas respostas e se eu quiser entender como o negócio funciona, estará tudo expressado no serviço de domínio.
Já no caso das validações necessárias às operações no serviço de aplicação, elas podem conter regras puramente do domínio, às vezes executando alguma lógica complexa pra considerar um objeto de domínio válido. Seria o caso de separar esse tipo de operação mais complexa num serviço de domínio, já que elas envolvem/expressam conhecimento do negócio?
Elemar, como vc mencionou a questão de adotar o uso de Stored Procedures para implementar uma interface de domínio, penso que esta abordagem dificultaria a implementação dos testes (visto que poderão haver regras de negócio dentro da SP). Neste caso, como você costuma resolver este dilema, ou seja, cobrir as regras contidas na SP com testes?
Mas se partimos do principio que a SP seria um update simples, porem que seria pesado e por isso foi trazido para o lado do banco para ganhar no desempenho?
Acredito que esse seja o caminho
Uma dúvida, um servico de domínio pode acessar um repositório de outro domínio? No exemplo extraído do Livro Vernon não entendi a qual domínio o AuthenticationService pertence, mas ele acessa dois repositórios que também não ficou claro se estão ou não no mesmo domínio, mas imaginando que estejam em domínios diferentes. Como fica a minha questão, pode um servico de domínio acessar repositório de outros domínios?
Ótimo vídeo, como todos os outros!
Uma dúvida:
Como funciona o"DomainRegistry" que aparece nos códigos mostrados? Parece ser uma classe estática uitlizada pra acessar a implementação de repositórios. Mas, como é implementado esse "DomainRegistry"?
Estou assumindo que as classes mostradas que usam o DomainRetistry estão no domínio. É isso mesmo?
Grato!
Ótimo vídeo. É comum termos um serviço de domínio algumas vezes grande, as vezes até com uma série de métodos privados ?
Eventualmente, sim! Depende da complexidade da operação sendo implantada.
Ao invés de colocar regra de negócio no Controller, eu costumo criar um Service, até mesmo para conseguir reaproveitar essa lógica em outra parte do sistema. Normalmente esse Service recebe no construtor a instância de um Repository. Com base no vídeo, este meu Service se enquadraria em qual tipo?
Posso estar errado, mas pra mim, application service.
Regra de negócio? Cuidado para seu modelo não estar anêmico.
@@elemarjr eu estou montando uma aplicação de exemplos para consultas futuras e até mesmo para ajudar amigos com programação. E percebi que criei um modelo de domínio anêmico. Toda a regra de negócio estava no serviço. Já me disseram que devo criar o modelo de domínio sem pensar em modelo de dados, depois de montar o domínio aí sim eu devo pensar em como persistir os meus dados, acredito que por já pensar em como iria persistir eu acabei colocando as regras no serviço e depois já chamava o repositório para persistir. Esquecendo de usar o meu domínio.
Eu utilizo serviço de domínio para validar dados exemplo validação de CPF e outras regras, com estes dados validado consigo mandar para o meu domínio e persistir no banco de dados
Importante destacar que essas validações também precisam ser feitas no domínio, caso contrário ele será anêmico. Na minha interpretação , você tem um serviço de aplicação.
@@elemarjr sim, uso ela tanto pra fazer a orquestração e chamar alguns eventos de dominio
elir ribeiro se há apenas orquestração, sem “decisão” você tem um serviço de aplicação (rimou)
Para o exemplo citado, CPF, tem outro vídeo do @Elemar Junior que pode te ajudar. O título é mais ou menos: 'uso
obsessivo de tipos primitivos'... Vai abrir sua mente para esse tipo de validação.
👍🏽
Exímio....
Uma dúvida por gentileza: ex: eu tenho uma entidade que tem um número sequencial que o usuário deve informar, só que na hora de gravar essa entidade, eu preciso validar se o último número gravado no banco de dados seja obrigatoriamente menor que o número que o usuário acabou de digitar. Esse tipo de validação deve ser criado em um SERVIÇO de domínio ou eu posso criar um método injetando o repositório dentro da classe da entidade mesmo?
Por que o usuário precisa fornecer esse número? Por que a aplicação não fornece?
Em tempo, seu problema pode ser difícil de escalar.
@@elemarjr Foi só uma situação hipotética. Na verdade minha dúvida é exatamente a mesma do Ricardo Carvalho (abaixo). Se for necessário validar uma entidade contra outra já persistida no BD, se uma domain service se enquadraria. Aproveitando, muito obrigado pela atenção e pelos conteúdos fantásticos. Melhores aulas que já tive!
Like 182°