Pergunta 1
Não há problema se o serviço de domínio usar serviços de infraestrutura, se os serviços de infraestrutura aceitarem e retornarem conceitos de domínio - entidades e objetos de valor.
Além disso, os serviços de domínio devem encapsular parte da lógica de negócios que não cabe em uma entidade. Portanto, saveUser
não é um ótimo método para um serviço de domínio.
A pergunta a fazer é - o envio de um email é um conceito de domínio importante? A Email
é uma entidade no seu domínio? Em caso afirmativo, você pode ter uma interface para um remetente de e-mail definido em sua camada de domínio, com uma implementação separada na camada de infraestrutura, e você poderia fazer o seguinte de forma significativa serviço de domínio -:
sendEmailIfWhiteListed(id) {
Email = this.emailRepository.get(id);
if (email.isWhiteListed) {
this.emailSender.send(email);
}
}
Mas isso é sensato apenas se os e-mails forem entidades em seu domínio. Se eles não são, então pense - por que fazer o envio do e-mail a responsabilidade de salvar o usuário?
No seu caso, não parece que os e-mails sejam entidades em sua linguagem onipresente . Então aqui eu sou a favor do padrão de eventos de domínio . Criar um novo usuário deve gerar um evento de domínio NewUserCreated
e o manipulador do evento de domínio, que eu colocaria na camada do aplicativo, delegaria a um remetente de email para enviar o email.
Questão 2
Quem é responsável por converter os dados de postagem em uma entidade significativa? Depende do que você está fazendo:
- Se adicionar um novo usuário
- Se for uma lógica simples, o serviço de aplicativo pode chamar
new Entity()
e passar argumentos de domínio significativos (valueobjects) mapeados a partir do apidata
argument - Se for uma lógica complexa, um serviço de domínio especial chamado fábrica pode ser usado
this.entityFactory.Create()
e, novamente, passar argumentos de domínio significativos (valueobjects) mapeados a partir do apidata
argument - Em ambos os casos, a entidade ou a fábrica não deve estar ciente da estrutura de
data
, pois essa é uma preocupação da API
- Se for uma lógica simples, o serviço de aplicativo pode chamar
- Se atualizar um usuário
- o serviço de aplicativo deve usar um repositório para obter o usuário existente
- o usuário deve ter métodos para atualizar dados relevantes. Mas eu fugiria de métodos no estilo CRUD como
user.update
- pense em por que os dados do usuário estão sendo atualizados? O DDD nos incentiva a pensar nos processos e objetivos do negócio.- O usuário está sendo atualizado porque participou de algum processo de negócios? Em seguida, modele o processo de negócios explicitamente e modifique os dados do usuário como um efeito colateral do processo
- O usuário está sendo atualizado devido a uma interação CRUD simples, como a edição de uma página de perfil? Mesmo assim, eu encorajaria um método de entidade como
user.UpdateProfile
a ser explícito sobre o propósito da operação.
DDD é sobre o idioma - ouça a linguagem usada por especialistas em domínio, concorde com uma linguagem ubiquitious e use-a fielmente em seu código. Se os especialistas do seu domínio não disserem persist
ou save
, não use essas palavras na sua camada de domínio.