DDD con ORM dove dovrebbe andare la logica di business?


10

In passato ho utilizzato uno strumento MDA (model driven architecture) in cui abbiamo modellato tramite UML e questo ha generato, tra le altre cose, le entità di business (il nostro modello di dominio) e l'ORM (mapping ecc.).

Gran parte del codice aziendale e dei servizi che lavorano sul dominio facevano parte del modello e i nostri repository restituivano le entità aziendali (quindi sarebbe stato impossibile passare a un altro ORM (non che volessimo)).

Tuttavia, ora sto iniziando un progetto e voglio pensare in termini di DDD.

Finora mi sembra di inserire la mia logica aziendale nel mio modello di dominio e tramite i repository lavorerei con l'ORM (che io abbia mai scelto). Tuttavia, se volessi continuare a utilizzare lo strumento MDA per la parte ORM dell'applicazione, il modello creato qui sarebbe molto anemico (ovvero non contenere alcuna logica aziendale). Allo stesso modo se usassi Entity framework (.net) o NHibernate per il mio ORM, sarebbe anche un modello anemico. Non sono sicuro di dove inseriresti la logica aziendale se avessi appena usato NHibernate.

Sono corretto nel pensare in questo modo, in altre parole con DDD tutta la logica aziendale nel dominio e usare l'ORM per la persistenza attraverso i repository?

Risposte:


12

quindi sarebbe stato impossibile passare a un altro ORM (non che volevamo)).

Sembra sbagliato. Un grande vantaggio del modello di repository è che si nasconde la logica di accesso ai dati e che è facilmente scambiabile.

Finora mi sembra di inserire la mia logica aziendale nel mio modello di dominio e tramite i repository lavorerei con l'ORM (che io abbia mai scelto). Tuttavia, se volessi continuare a utilizzare lo strumento MDA per la parte ORM dell'applicazione, il modello creato qui sarebbe molto anemico (ovvero non contenere alcuna logica aziendale). Allo stesso modo se usassi Entity framework (.net) o NHibernate per il mio ORM, sarebbe anche un modello anemico. Non sono sicuro di dove inseriresti la logica aziendale se avessi appena usato NHibernate.

Un modello di dominio anemico è considerato una cattiva pratica da molti, ad esempio da Martin Fowler. Dovresti evitare un tale progetto perché un tale modello porta a tecniche di progettazione procedurale piuttosto che a un buon design orientato agli oggetti. Quindi hai classi di dati e classi di gestione / elaborazione, il che significa che hai separato stato e comportamento. Ma un oggetto dovrebbe davvero essere "stato e comportamento".

NHibernate fa un ottimo lavoro nell'ignoranza della persistenza. Puoi nascondere i dettagli della mappatura in XML o con FluentNHibernate e scrivere semplicemente POCO. È molto semplice creare un modello di dominio avanzato con NHibernate. Penso che tu possa farlo anche con il framework di entità e lo strumento MDA. Finché questo strumento produce classi parziali, puoi estendere il codice generato abbastanza facilmente senza doversi preoccupare che una nuova generazione possa distruggere il tuo codice scritto dall'utente.

Per farla breve. Quando usi NHibernate, niente, non ripeto nulla , ti impedisce di abbracciare un ricco modello di dominio. Consiglio di usarlo con FluentNHibernate e di mapparlo a mano. La scrittura del codice di mappatura richiede solo da 5 a 10 minuti. Suppongo che lo stesso valga per il framework delle entità e che i suoi strumenti almeno creino classi parziali facilmente estensibili.

Sono corretto nel pensare in questo modo, in altre parole con DDD tutta la logica aziendale nel dominio e usare l'ORM per la persistenza attraverso i repository?

Per la maggior parte hai ragione. Dovresti avere un modello di dominio avanzato. Soprattutto quando le cose diventano sempre più complesse, è più facile da mantenere ed estendere quando le hai progettate correttamente. Ma tieni presente che DDD conosce anche i servizi (Domain Layer e Application Layer) per implementare la logica aziendale e le fabbriche per incapsulare la logica creazionale.

Inoltre, tendo a differenziare la logica aziendale in logica di dominio e logica aziendale effettiva dell'applicazione. La logica del dominio è il modo in cui il dominio interagisce e si comporta mentre la logica dell'applicazione, che è un livello completamente diverso, incapsula il modo in cui il dominio viene utilizzato per il caso d'uso / l'applicazione specifici. Spesso devo aggiornare il modello di dominio per supportare casi d'uso specifici e renderlo più potente.


2
+1: separo anche il livello logico di dominio dal livello logico dell'applicazione. Ho inserito tutte le cose ORM e di database nel livello logico del dominio. Il livello di logica dell'applicazione non sa nulla dell'ORM, delle transazioni e di tutto ciò: vede solo le classi di logica aziendale e chiama i loro metodi. Trovo questo approccio molto efficace per avere un livello logico di applicazione più semplice e pulito.
Giorgio,

@Falcon: grazie per le informazioni. Quando ho citato il modello anemico ciò che intendevo era se creavo un dominio usando DDD, una versione dei miei repository sarebbe stata probabilmente la versione mda in cui avrei semplicemente spostato le mie entità nelle entità mda (cioè modello anemico) e poi li avrei persisti nelle transazioni ecc. Andrebbe bene? Dubito che userò lo strumento MDA ma cerco solo di capire come potrei se volessi. Suona bene?
JD01,

@ JD01: non ti capisco del tutto, ma sembra che tu voglia trasformare entità del modello di dominio in modo da poterle perseverare facilmente. È praticamente come usare DTO e automapper (google it) potrebbe essere uno strumento utile per tale compito. Un tale approccio non interferisce necessariamente con le migliori pratiche DDD. Dopotutto, i repository hanno anche lo scopo di nascondere la logica di accesso ai dati. Potresti semplicemente trasformare i tuoi oggetti Business dietro le quinte in DTO MDA e poi perseverarli e l'utente API non se ne accorgerebbe nemmeno. Penso che sia ok.
Falcon,

1
@ JD01: ti suggerisco di dare un'occhiata al seguente link per vedere quanti ragazzi Enterprise java lo fanno. Fondamentalmente hanno un DAO, un DTO e un BO (Business object). Per me sono troppi strati ma il design è ok. java.sun.com/blueprints/corej2eepatterns/Patterns/…
Falcon

@Falcon: Sì, pensavo che i DTO fossero i miei oggetti MDA, non che andassi in quel modo. Basta avere un'idea di ciò che ogni parte dei giocatori DDD d0. Grazie ancora.
JD01,

3

Tuttavia, se volessi continuare a utilizzare lo strumento MDA per la parte ORM dell'applicazione, il modello creato qui sarebbe molto anemico (ovvero non contenere alcuna logica aziendale).

Non so quale strumento MDA stai usando, ma quelli con cui ho lavorato creano sempre classi parziali, quindi sei libero di completarle con tutta la logica aziendale che desideri.

Tuttavia, ritengo che gli strumenti MDA siano un po 'meno appropriati in un contesto DDD rispetto agli ORM, poiché la generazione del codice tende spesso a produrre classi confuse con rumore specifico dello strumento invece delle entità di dominio semplificate e chiaramente espresse che ci aspettiamo. In realtà, quello che ottieni spesso è un mix di dati di dominio, logica di persistenza, logica di convalida dei vincoli ... e non so se c'è un modo per separare queste preoccupazioni con la maggior parte degli strumenti MDA.

E, naturalmente, non puoi toccare il codice generato se non tramite classi parziali, il che significa che non puoi eliminare il potenziale comportamento anti-DDD che sarebbe integrato. Ciò è problematico in un approccio in cui si desidera applicare barriere rigorose tra aggregati e personalizzare perfettamente le relazioni tra le entità. Anche i tempi di costruzione in un ambiente di integrazione continua possono risentire della fase aggiuntiva di generazione del codice.

A parte questo, penso che Falcon abbia praticamente detto tutto: assolutamente nulla negli strumenti ORM o MDA ti impedisce di avere entità di dominio avanzate.


Ciao, sto usando ECO (oggetti core aziendali) da ableobjects.com ed è esattamente come l'hai descritto.
JD01,

1

Quello che faccio nel mio team è modellare il mio oggetto, dominio e aggiungere la mia logica aziendale allo stesso tempo. Non uso Model Driven Development che genererebbe un codice da un modello ma preferisce l'approccio di annotazione. Voglio dire che a livello di oggetto all'interno del diagramma di classe aggiungo stereotipi ORM. Ciò aggiungerà direttamente nel codice le annotazioni di persistenza compatibili con EJB3 / ibernazione. La creazione del database viene eseguita da Hibernate e certamente non dai modelli UML. Questo è molto meglio perché se il codice cambia e le annotazioni aggiunte non sono esattamente ciò che lo specialista del letargo può cambiare, ma il modello è ancora buono. Posso anche cambiare i miei requisiti e il mio modello di dominio è ancora ok.

Gli sviluppatori possono aggiungere la logica di business all'interno di ogni metodo e aggiungere un commento, posso anche modellare e aggiungere vincoli. Ad esempio, le vendite dovrebbero essere superiori a 50k se non ecc. Ecc. Non ho bisogno di codificarlo, ma basta scrivere nel modello e queste informazioni dovrebbero essere visibili al team di sviluppatori. UML davvero interessante e flessibile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.