2009-09-05 15 views
14

Sto imparando DDD e io sono un po 'perso nel livello di infrastruttura:DDD servizi di infrastruttura

quanto ho capito, "tutte le buone applicazioni DDD" dovrebbe avere 4 strati: Presentazione, Applicazione, Dominio e delle Infrastrutture. È necessario accedere al database utilizzando i repository. Le interfacce del repository devono trovarsi in livello di dominio e implementazione del repository - in Infrastruttura (riferimento DDD: Where to keep domain Interfaces, the Infrastructure?).

Applicazione, dominio e infrastruttura devono/possono avere servizi (riferimento www.lostechies.com/blogs/jimmy_bogard/archive/2008/08/21/services-in-domain-driven-design.aspx), ad esempio EmailService nel livello Infrastruttura che invia messaggi di posta elettronica.

MA, all'interno del livello Infrastruttura abbiamo implementazioni di repository, che vengono utilizzate per accedere al database. Quindi, in questo caso, i repository sono servizi di database? Qual è la differenza tra servizio di infrastruttura e repository?

Grazie in anticipo!

risposta

14

Attenendosi alle definizioni DDD, un repository è diverso da un servizio. Un repository è direttamente correlato a un'entità, spesso una radice aggregata. Un servizio definisce comportamenti che non appartengono veramente a una singola Entità nel tuo dominio. Puoi trovare assolutamente i Servizi in ogni livello, anche se i tipi di problemi che affrontano differiscono da un livello all'altro e possono essere diversi dal Servizio concettuale di DDD.

Quando si lavora a livello concettuale, un repository DDD si differenzia da un servizio DDD in quanto è specificamente legato alla persistenza delle Entità. Un servizio può risolvere qualsiasi problema di dominio, applicazione o infrastruttura che potresti avere.

Si imbattono in scontri terminologici con DDD dappertutto. Ad esempio, un deposito DDD NON è la stessa cosa del Repository pattern trovato nel libro PoEAA di Martin Fowler, sebbene possa impiegare un tale schema. Questo è spesso fonte di confusione per molte persone.

Aiuta con DDD se si mantiene sempre il modello di dominio al centro di tutto ciò che si fa. Quando si tratta di stratificare le app DDD, spesso scelgo lo Jeffrey Palermo's Onion Architecture. Controlla. Scarica CodeCampServer, un'app di esempio che utilizza questa architettura. Penso che sia perfetto per la programmazione DDD.

Buona fortuna!

7

Una cosa spiacevole per DDD è la parola "Servizio". Quello che dovrebbe essere è 'Domain Service'. Pensa al dominio come entità e oggetti valore, mentre i servizi sono un modo per gestire azioni, operazioni e attività.

Come per i repository, sono solo una facciata che dovrebbe comportarsi come una raccolta per il tuo dominio. Se si sta utilizzando un ORM o si scrive da soli, questo è ciò che dovrebbero passare tutti gli oggetti del dominio per raggiungere la persistenza anziché quei servizi direttamente.

+0

Beh, forse hai frainteso la mia domanda, o ho frainteso la risposta. All'interno del livello dell'infrastruttura, se disponiamo di un servizio che si occupa dell'API di posta, lo chiamiamo "servizio di posta elettronica", ma il codice per recuperare i dati dal database è chiamato "implementazione del repository". Non è lo stesso tipo di "servizio di infrastruttura"? – Zygimantas

-1

Perché mettere le implementazioni del repository in Infrastruttura? Non sono affatto collegati a "Infrastruttura". Principalmente ho inserito le interfacce del repository nel "modello di dominio" e ho inserito anche l'implementazione di questi repository nel modello di dominio.

L'infrastruttura deve contenere il codice "infrastruttura", che potrebbe essere un servizio che consente di inviare facilmente messaggi di posta elettronica tramite smtp o codice che astrae l'accesso al DB per voi (quindi, alcune classi che è possibile utilizzare nel repository, ma non è il tuo repository).

Quindi, non mettere i repository in "infrastruttura", dato che non ci appartengono. Per me, le classi che possono essere trovate nell'infrastruttura, sono classi che puoi usare in diversi altri progetti, vedi cosa intendo? Le classi che non sono strettamente correlate al modello di dominio o all'applicazione appartengono a Infrastructure. E l'implementazione di un repository è strettamente collegata a un'applicazione specifica. :)

+1

Vedo i repository come specifici del dominio, non necessariamente specifici dell'applicazione. Guardando in questo modo, ha senso avere un'interfaccia repository definita nel livello del modello di dominio. Vedo l'accesso ai dati come un problema di infrastruttura specifico del dominio, separato dal codice dell'applicazione.Vedo quello che stai dicendo sulle librerie riutilizzabili, ma separo quelle librerie in diversi moduli: uno (o più) moduli riutilizzabili, contenenti classi come EmailSender e uno (o più) moduli infrastrutturali specifici del dominio, contenenti classi come CustomerRepository. Moduli diversi, stesso livello. –

+0

In effetti, l'implementazione del repository non dovrebbe essere nell'applicazione. Dovrebbe essere nel modello di dominio. Tuttavia, il livello dell'applicazione deve controllare l'ambito di transazione utilizzato da un repository. –

+0

Penso che un repository tradizionale dovrebbe essere implementato al di fuori del modello di dominio se ospita l'infrastruttura reale per l'accesso ai dati. Ma con il concetto di NWorkspace di Jimmy Nilsson penso che gli archivi possano avere un'implementazione non infrastrutturale spostata nel livello del dominio in cui ha più senso. – jpierson

5

Forse aiuterà a vedere una potenziale struttura di progetto.

assemblaggio o il pacchetto possibile struttura:

Project.Domain
Project.Infrastructure.Data
Project.Infrastructure.Components
Project.Infrastructure.Services

Possibile spazio dei nomi o la cartella struttura:

Progetto.Dominio
Moduli -n-
---- conto n-
------- f- Account.xx
------- f- AccountRepository.xx
----- --f- Contact.xx
---- n- Marketing
------- f- RegionRepository.xx
-n- condiviso
-n- Servizi

Project.Infrastructure .Data (OR-Mappers)
-n- Tabelle
-n- Visualizzazioni
Procedure -n-
Funzioni -n-

Project.Infrastructure.Components (generico)
-n- posta
Cryptography -n-
-n- UI

Project.Infrastructure.Services (Special Operations)
-F- DoingSomethingService1.xx
-F- DoingSo methingService2.xx
-F- DoingSomethingService3.xx

entità del dominio e Tipi di valore non utilizzano Servizi di dominio. Il livello applicazione utilizza i servizi del dominio. Gli oggetti del repository di dominio utilizzano gli oggetti Infrastructure.Data per restituire gli oggetti Dominio.

+2

Il punto di DDD non deve avere una certa struttura di progetto, ma piuttosto avere un comportamento sulle entità. Quando dici "fai copie dei tuoi oggetti ORM" sembra che tu stia usando un dominio anemico, che in realtà non è affatto DDD. Il comportamento (mutazioni dello stato del dominio) deve essere all'interno degli oggetti dominio, non nei servizi. – Ryan

+0

Ovviamente, Ryan. DDD NON riguarda un determinato tipo di progetto. Questo è un dettaglio di implementazione. Ecco perché ho detto che può aiutare a vedere una struttura di progetto. Con "fare copie", sto parlando nel contesto di attributi, NON il comportamento. L'oggetto dominio assomiglierà per la maggior parte all'oggetto del database. Cosa significa? Significa che gli attributi saranno simili ad eccezione delle associazioni Aggreate e Composition. Dal momento che ti ho confuso, rimuoverò quel testo. Se ti ha confuso, sono sicuro che confonderà gli altri. –

+0

Penso che intendiate proprietà, non attributi. Non intendo criticare, solo per chiarire. Sono del pensiero che le proprietà su un oggetto di dominio siano un anti-modello. Ultimamente ho seguito una rotta quasi-cqrs: leggere solo le proprietà sul mio dominio e i metodi per modificare lo stato. Le mie visualizzazioni corrispondono a circa il 50% delle letture DB denormalizzate e al 50% di proiezione fuori dal modello di dominio. L'approccio che scelgo dipende solo dalla complessità dei dati. – Ryan