I servizi di dominio possono accedere ai repository? Oppure dovrebbero lavorare su aggregati/entità trasmessi loro da Application Services?I servizi di dominio possono accedere ai repository?
Considerare due esempi di codice della stessa operazione commerciale - trasferimento di denaro. Come primo passo, modifico i saldi dei conti. Quindi ottengo l'e-mail di notifica e invio la notifica. Lo so, probabilmente dovrei astrarre il modo in cui vengono inviate le notifiche (e-mail, SMS, piccione viaggiatore), ma per semplicità supponiamo che ora supportiamo solo le e-mail.
La variante 1 utilizza repository all'interno del servizio di dominio. La variante 2 risolve le dipendenze nel servizio dell'applicazione e le passa a TransferDomainService
.
In questo esempio l'operazione è semplice (sottrarre denaro da un account e aggiungerlo a un altro). Ma se ci fossero più regole aziendali coinvolte (possibile richiedere l'accesso a più aggregati)? Se viene applicata la variante 2, il servizio dell'applicazione deve essere a conoscenza di cosa richiede esattamente il servizio di dominio. Se viene scelta la variante 1, il servizio di dominio richiede ai repository ciò che richiede per eseguire il proprio compito.
(Note su frammenti:. Codice Groovy per mettere a nudo la verbosità di Java blocchi DDD inclusi nei nomi)
Variante 1
class TransferApplicationService {
def transferDomainService
def customerDomainService
def emailNotifierInfrastructureService
def transfer(fromAccount, toAccount, amount) {
transferDomainService.transfer(fromAccount, toAccount, amount)
def email = customerDomainService.accountNotificationEmail(toAccount)
emailNotifierInfrastructureService.notifyAboutTransfer(email, amount)
}
}
class TransferDomainService {
def accountRepository
def transfer(fromAccount, toAccount, amount) {
def from = accountRepository.findByNumber(fromAccount)
def to = accountRepository.findByNumber(toAccount)
to.decreaseBalance(amount)
from.increaseBalance(amount)
}
}
Variante 2
class TransferApplicationService {
def accountRepository
def transferDomainService
def customerDomainService
def notifierInfrastructureService
def transfer(fromAccount, toAccount, amount) {
def from = accountRepository.findByNumber(fromAccount)
def to = accountRepository.findByNumber(toAccount)
transferDomainService.transfer(from, to, amount)
def email = customerDomainService.accountNotificationEmail(toAccount)
notifierInfrastructureService.notifyAboutTransfer(email, amount)
}
}
class TransferDomainService {
def transfer(fromAccount, toAccount, amount) {
to.decreaseBalance(amount)
from.increaseBalance(amount)
}
}
Sì.Un servizio di dominio è ancora un orchestratore solo la sua area di competenza è più limitata – MikeSW
@MikeSW intendi per "Sì" "Servizi di accesso ai repository" o "funzionano su aggregati/entità passate loro da Application Services"? – mgryszko
Sì alla domanda del titolo. – MikeSW