Quindi, dopo aver letto "Implementing Domain-Driven Design by Vaughn Vernon", ho deciso di ridefinire il mio codice per una migliore riutilizzabilità isolando ciò che ritengo essere concetti di dominio centrale in moduli separati.
Ogni modulo contiene il proprio insieme di livelli architettonici distinti che includono il dominio, l'infrastruttura e il livello di applicazione / presentazione (per raccomandazione di Vaughn ho deciso di separare ulteriormente le responsabilità del livello applicazione dalle rotte, controller MVC + modelli che esiste nel livello di presentazione).
Ho deciso di inserire ciascuno di questi livelli all'interno del proprio pacchetto; e ogni pacchetto fa riferimento al livello sottostante come dipendenza. Ad esempio: il livello di presentazione dipende dal livello applicazione, dall'applicazione dipende dall'infrastruttura, ecc. Poiché il repository fa parte del dominio, ogni interfaccia del repository esiste all'interno del livello / pacchetto dominio con l'implementazione come una responsabilità del livello / pacchetto infrastruttura (Doctrine , ecc.)
Spero che, ristrutturando il mio codice in questo modo, riuscirò a sostituire il livello dell'applicazione e riutilizzare il mio dominio su più applicazioni Web.
Sembra che il codice stia iniziando a formarsi di nuovo, tuttavia ciò che ancora mi confonde è questa distinzione tra Application, Infrastructure e Domain Services.
Un esempio comune di servizio di dominio è qualcosa che useresti per le password hash. Questo ha senso per me da una prospettiva SRP in quanto l'entità utente non dovrebbe preoccuparsi dei numerosi algoritmi di hashing che potrebbero essere utilizzati per memorizzare le credenziali di un utente.
Quindi con questo in mente ho trattato questo nuovo servizio di Dominio allo stesso modo dei miei Archivi; definendo un'interfaccia nel dominio e lasciando l'implementazione fino al livello infrastruttura. Tuttavia, ora mi chiedo cosa dovrebbe essere fatto con i servizi di applicazione.
Allo stato attuale, ogni Entità ha il proprio Servizio Applicativo, cioè l'Entità Utente ha un UserService all'interno del Livello Applicazione. In questo caso, UserService è responsabile dell'analisi dei tipi di dati primitivi e della gestione di un caso d'uso comune "UserService :: CreateUser (nome stringa, e-mail stringa, ecc.): Utente.
Ciò che mi preoccupa è il fatto che dovrò implementare nuovamente questa logica su più applicazioni nel caso decidessi di sostituire il livello Application. Quindi immagino che questo mi porti alle mie prossime domande:
-
I servizi di dominio sono semplicemente un'interfaccia esistente per fornire un livello di astrazione tra il livello dell'infrastruttura e il modello? es .: Repository + HashingServices, ecc.
-
Ho detto di avere un servizio applicativo che assomiglia a questo:
-
Accesso / Applicazione / Servizi / UserService :: CreateUser (nome stringa, email stringa, ecc.): Utente
-
La firma del metodo accetta argomenti di tipo dati primitivi e restituisce una nuova Entità utente (non un DTO!).
Questo appartiene al livello Infrastruttura come un'implementazione di alcune interfacce definite all'interno del livello Dominio o il livello di applicazione in effetti è più appropriato a causa di argomenti di tipo di dati primitivi, ecc. ?
esempio:
Access/Domain/Services/UserServiceInterface
e
Access/Infrastructure/Services/UserService implements UserServiceInterface
-
-
Come dovrebbero i moduli separati gestire le relazioni unidirezionali. Dovrebbe il livello applicativo del modulo B del modulo di riferimento A (come sta facendo ora) o l'implementazione dell'infrastruttura (tramite interfaccia separata)?
-
I servizi Application Layer richiedono un'interfaccia separata? Se la risposta è sì, dove dovrebbero essere collocati?