Nonostante abbia studiato a lungo lo Domain Driven Design
, ci sono ancora alcune nozioni di base che ho semplicemente capito.Problemi nel mettere la logica del mondo reale nel livello di dominio DDD
Sembra che ogni volta che cerco di progettare un ricco domain layer
, ho ancora bisogno di un sacco di Domain Services
o di una spessa Application Layer
, e io alla fine con un gruppo di entità del dominio quasi anemici con alcuna logica vera in loro, a parte da "GetTotalAmount" e simili. Il problema chiave è che le entità non sono consapevoli di cose esterne, ed è una cattiva pratica iniettare qualsiasi cosa in entità.
Vi faccio alcuni esempi:
1. A utente si inscrive per un servizio. L'utente è persistente nel database, un file viene generato e salvato (necessario per l'account utente) e viene inviata un'e-mail di conferma.
L'esempio con l'e-mail di conferma è stato ampiamente discusso in altri thread, ma senza una vera conclusione. Alcuni suggeriscono di inserire la logica in un application service
che ottiene uno EmailService
e FileService
iniettato dallo infrastructure layer
. Ma allora avrei una logica di business al di fuori del dominio, giusto? Altri suggeriscono la creazione di un domain service
che ottiene il infrastructure services
iniettato - ma in quel caso avrei bisogno di avere le interfacce del infrastructure services
all'interno del domain layer
(IEmailService
e IFileService
) che non sembra troppo buono (perché il domain layer
non può fare riferimento alla infrastructure layer
) . Altri suggeriscono di implementare lo Udi Dahan's Domain Events e quindi di inviare EmailService e FileService a tali eventi. Ma sembra un'implementazione molto sciolta - e cosa succede se i servizi falliscono? Per favore fatemi sapere cosa ne pensate sia la soluzione giusta qui.
2. Una canzone viene acquistata da un negozio di musica digitale. Il carrello è svuotato. L'acquisto è persistente. Il servizio di pagamento è chiamato. Viene inviata un'email di conferma.
Ok, questo potrebbe essere correlato al primo esempio. La domanda qui è, chi è il responsabile dell'orchestrazione di questa transazione? Naturalmente potrei mettere tutto nel controller MVC con servizi iniettati. Ma se voglio il DDD reale, tutte le logiche di business dovrebbero essere nel dominio. Ma quale entità dovrebbe avere il metodo "Acquista"? Song.Purchase()
? Order.Purchase()
? OrderProcessor.Purchase()
(servizio di dominio)? ShoppingCartService.Purchase()
(servizio applicazione?)
Questo è un caso in cui ritengo sia molto difficile utilizzare la logica di business reale all'interno delle entità di dominio. Se non è buona pratica di iniettare niente nelle entità, come possono mai fare altre cose che controllare il proprio stato (e del suo aggregato)?
Spero che questi esempi sono abbastanza chiare per mostrare i problemi che ho a che fare.
DDD suggerisce di rendere le entità 'File' e' Email' del dominio.L'infrastruttura è responsabile di generare effettivamente un file e di inviare effettivamente una e-mail quando le entità corrispondenti appaiono nel livello di dominio. – Lightman