DDD - Il modello di dominio anemico è un antipattern? Vuoi usare modelli di dominio avanzati? [chiuso]


11

Il modello di dominio anemico è stato criticato molto tempo fa da Evans e Fowler , poiché apparentemente va contro i principi orientati agli oggetti, ecc. La comunità DDD è chiaramente allineata con queste affermazioni.

Tuttavia, negli ultimi anni ci sono state voci in disaccordo che affermano che non è affatto un antipasto e che è un esempio dei seguenti principi SOLIDI.

Lavoro da tanti anni con Spring Framework. Ogni progetto in ogni azienda ha sempre avuto un livello di servizio contenente la logica di business, utilizzando repository che operano su modelli anemici (entità JPA). Inoltre, la maggior parte dei campioni, anche quelli ufficiali dei ragazzi di Spring, mostrano questo modo di lavorare.

Le mie domande sono: il modello di dominio anemico è ancora considerato un antipattern? Abbiamo fatto tutti cose sbagliate (riguardo al DDD)? Non pensi che avere modelli Rich Domain violi i principi SOLIDI?


2
"il modello di dominio anemico è ancora considerato un antipattern? ". Per alcuni, sì. Da altri, me compreso, lo vedo come il modo preferibile di scrivere codice la maggior parte delle volte, ma se l'RDM fa per te, usalo. Quindi votando per chiudere questo come puramente basato sull'opinione pubblica.
David Arno,

1
Questa sarebbe una domanda fantastica per un forum di discussione / dibattito; ma al momento non esiste una risposta autorevole. Preferiamo domande a cui si possa rispondere, non solo discutere.
VoiceOfUnreason,

Risposte:


9

ADM è un buon modello per una soluzione di servizi distribuiti come microservizi. Si adatta a molti dei casi aziendali di oggi basati sul web.

Considera se abbiamo un oggetto Dominio ordine. Con un approccio OOP aggiungeremmo Order.Purchase () Order.Cancel () ecc. Funzionerebbe bene in un'app desktop, dove conserviamo gli ordini in memoria e facciamo più cose nella stessa istanza.

Ma se abbiamo un sistema distribuito, con programmi che riguardano solo una cosa, ovvero accedere a un elenco di ordini e acquistarli a turno, oppure ottenere un elenco di ordini e cancellarli a turno, avere entrambi i metodi sullo stesso oggetto non fa senso. Dovremmo avere due domini o contesti limitati:

PurchaseSystemOrder.Purchase()

e

CancelSystemOrder.Cancel();

L'unica cosa che questi oggetti condividono sarebbe la struttura dei dati delle proprietà.

Man mano che aggiungi sempre più microservizi, finisci con dozzine di tipi di ordine. Non ha più senso parlare di un Ordine come oggetto Dominio, anche se è lo stesso ordine concettuale che viene elaborato da tutti questi sistemi.

Ha molto più senso avere un modello Anemic, Order, che incapsula solo i dati e rinominare i servizi di conseguenza:

PurchaseService.Purchase(Order order)

Ora possiamo parlare di nuovo di Order e possiamo aggiungere qualsiasi nuovo servizio che pensiamo di elaborare, senza influire sugli altri servizi attualmente distribuiti.

Fowler e Co provengono da un background di sistema monolitico, nel loro mondo un approccio ADM significherebbe un'unica app con tutti questi servizi separati istanziati in memoria e OrderDTO viene fatto circolare e mutato. Questo sarebbe molto peggio che mettere i metodi su un ricco modello di Ordine.

Ma in un sistema distribuito, ci sono molti programmi, ognuno richiede solo un singolo metodo Ordine e lo esegue su più ordini, caricandoli ciascuno, eseguendo il metodo e quindi scartandolo. Richiede solo un singolo servizio e un flusso di oggetti dati.

Il popolamento completo di un modello completo, preoccuparsi dei requisiti e delle dipendenze di tutti i metodi solo per chiamarne uno singolo e scartare l'oggetto quasi immediatamente è inutile.

Inoltre, una modifica a uno dei metodi richiederebbe l'aggiornamento di tutti i componenti distribuiti poiché dipendono tutti dal modello Rich per la loro logica.

Non ho spazio nella mia base di codice per le cose di cui non hanno bisogno


4
Ho effettuato il downvoting perché penso che DDD sia particolarmente adatto ai microservizi proprio a causa del concetto di contesto limitato. Penso che il problema con la tua risposta sia che il concetto e la classe dell'Ordine siano gli stessi per ogni micro-servizio, ma penso che non sia né necessario né accurato.
RibaldEddie,

Non sono in disaccordo, ADM può essere DDD se chiami il registratore di cassa PurchaseService e lo rendi parte della tua lingua di dominio
Ewan

Puoi elaborare? Ho sempre pensato che YMMV quando ADM e DDD erano in una base di codice EF SOLID J2EE o .NET C # MVC.
RibaldEddie,

Ciò che intendo è che il contesto limitato Order, PurchaseSystemOrder.Purchase () sarà praticamente identico al codice CashRegister.Purchase (Order order) è solo una modifica di denominazione nella lingua del tuo dominio. Un modello di dominio avanzato significa avere entrambi i metodi di acquisto e annullamento nella stessa classe.
Ewan,

1
@RibaldEddie, Sulla scia dello spessore del libro "javaScript, le parti buone", offro questa immagine come argomento (non del tutto serio) contro l'uso di DDD per l'implementazione di microservizi;)
David Arno,

3

SOLID e DDD sono ortogonali tra loro, il che significa che stanno davvero andando in direzioni diverse l'una dall'altra. Non dovresti dire che uno è usato ad esclusione dell'altro, poiché possono e dovrebbero probabilmente esistere insieme nella stessa base di codice.

I modelli di dominio anemico diventano un modello anti-pattern solo quando il dominio problematico ha un comportamento elevato e si dispone di centinaia di metodi di servizio con molta logica o dipendenze incollate in cui i metodi del livello di servizio devono chiamare altri metodi del livello di servizio per eseguire qualsiasi operazione.

DDD è un paradigma eccellente per i micro-servizi grazie al concetto di contesto limitato .

Fai attenzione alla tentazione di vedere il codice dell'infrastruttura come parte del tuo dominio. Il codice dell'infrastruttura è tutto ciò che non è stato scritto dall'utente o è associato a un framework o una libreria che interagisce con un sistema di terze parti. Connessioni al database, mailer SMTP, librerie ORM, tempi di esecuzione del server delle applicazioni, tutto ciò che è infrastruttura e non dovresti includerlo o dipenderlo nel tuo dominio se puoi evitarlo.

I principi SOLID sono un insieme di concetti OOP generici che è possibile utilizzare per creare un codice OOP migliore. È possibile scrivere una buona base di codici DDD utilizzandoli.


Per quanto riguarda la separazione del codice dell'infrastruttura dal dominio. Finora avevo considerato le Entità JPA come il mio dominio, con i seguenti livelli applicativi: controller -> servizio -> repository -> dominio (Entità JPA). Quali sarebbero i modi giusti (o uno dei giusti) per modellarlo secondo il tuo punto? Qualcosa come: controller -> modello ricco -> x? Come e dove dovrei occuparmi della transazionalità? E la mappatura di JPA? Non dovremmo duplicare il nostro ricco modello con entità JPA separate?
codipendente il

Un'entità JPA è un semplice vecchio oggetto Java. La mappatura fa parte dell'infrastruttura ma la classe stessa non deve esserlo. Se si sceglie di trattarlo come parte dell'infrastruttura, è necessario considerarlo come un oggetto di trasferimento dati utilizzato in Factory o nel repository per creare un'entità dominio.
RibaldEddie,

1

Un dominio ricco è bello se fatto bene. Un incubo quando no. Un dominio anemico è sempre negativo. Ma è un tipo familiare di male.

Se un dominio anemico è tutto ciò che desideri, hai scelto la lingua sbagliata quando hai scelto una lingua per scopi generici. Le lingue di quarta generazione sono specializzate in un uso specifico. Se l'anemico è abbastanza buono usarli ti avrebbe semplificato la vita.

Molti framework si diffondono nello spazio linguistico fino a quando non è più possibile pubblicizzare il lavoro come lavoro java. È un lavoro Java / Spring. Quello che stanno facendo, oltre a farti dipendere da loro, è trasformare una lingua per scopi generici in una forma bastarda di una lingua di quarta generazione.

È una buona pratica o un modello anti? Bene, il tuo capo si preoccupa solo se puoi assumere persone per lavorare sulla base di codice. Quindi, se dobbiamo fingere di usare un linguaggio generico per assumere persone, lo faremo.

Se stai bene, allora va bene. Di certo non sei l'unico.

Ma non dirmi che è così che deve essere. Non dirmi che sta facendo qualcosa per me più di quanto non sia. So vivere senza di essa. So come espellerlo, quindi solo poche cose dipendono da esso. Se mi stai chiedendo di arrendermi e lasciare che prenda il controllo di tutto solo perché combatterlo è troppo difficile, sì, penso che sia male.

Non ho spazio nella mia base di codice per cose di cui non ha bisogno.

Per quanto riguarda SOLID e gli altri principi di progettazione, posso seguire ampiamente quelli anche in un dominio anemico. Non seguirli causa un diverso tipo di problema.


Apprezzo la tua risposta e sono assolutamente d'accordo sul fatto che alcuni framework come Spring o JPA-Hibernate abbiano conquistato il panorama di Java. Tuttavia è anche innegabile che abbiano fornito una serie di buone pratiche e semplificazioni che Java (JEE) non ha affrontato affatto o fatto in modo errato. Sono davvero entusiasta di DDD e vorrei capire tutti i principi che dicono. esperienza, quali sono le migliori piattaforme / lingue / framework per lavorare con app DDD pure (con modelli Rich Domain)? Qualche buon esempio di Github che conosci? Come dici tu, voglio fare bene le cose, non conformarmi con le cattive pratiche.
codipendente il

Non facciamo raccomandazioni sulle risorse qui. Ma credo che un adeguato livello di infrastruttura che si occupi di framework significhi che puoi usare qualsiasi tipo ti piaccia. Trattali come una biblioteca. Tienili a conoscenza fuori dal dominio. Inoltre, non fare affidamento sulla magia. Resisti alla tentazione di usare cose che non potresti farti. Perché un giorno potresti averne bisogno.
candied_orange,

Tornando al punto originale. Che dire dei principi SOLIDI? I modelli di domini ricchi si assumono molte responsabilità, persistenza (JPA), logica aziendale (dovendo occuparsi della transazionalità), ecc. I modelli anemici, d'altra parte, si preoccupano solo della persistenza avendo servizi separati che si occupano di logica aziendale. Sembra anche più facile da testare. Cosa c'è di così sbagliato allora?
codipendente il

La cosa principale è iniziare a fare scelte progettuali basate sui bisogni dei sistemi piuttosto che sui bisogni semantici. È sottile, facile da ignorare, il costo non è ovvio e difficile da giustificare. In breve, è come sostenere che le linee elettriche dovrebbero essere sepolte piuttosto che nei sondaggi. Una volta che le persone si abituano all'alternativa economica, non è probabile che cambi. Anche quando gli uragani eliminano il potere.
candied_orange,

1
Ti avrei dato il beneficio del dubbio sulla tua affermazione che "Un dominio ricco è bello se fatto bene. Un incubo quando no." Forse non l'ho mai visto fare bene, ma poi fai un'assurdità dicendo che "Un dominio anemico è sempre male". Assurdità supposte che rendono inutile la tua risposta. -1
David Arno,
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.