Un modello di dominio ricco dovrebbe disporre di repository iniettati in alcune situazioni?

3

Vedi il codice qui sotto, che ho preso dai modelli di dominio malvagi di Jimmy Bogards:

public Offer AssignOffer(OfferType offerType, IOfferValueCalculator valueCalculator)
        {
            DateTime dateExpiring = offerType.CalculateExpirationDate();
            int value = valueCalculator.CalculateValue(this, offerType);

            var offer = new Offer(this, offerType, dateExpiring, value);

            _assignedOffers.Add(offer);

            NumberOfActiveOffers++;

            return offer;
        }

Purtroppo non ha pubblicato il codice contenuto nell'implementazione di: IOfferValueCalculator. Ho la sensazione che la classe conterrà la logica che determina ciò che offre un membro ha diritto a. Tuttavia, sicuramente l'oggetto dominio deve andare nel database (tramite il repository) per ottenere i dettagli delle offerte, ad es. data in scadenza ecc. Tuttavia, capisco che il livello del dominio in un modello di dominio ricco non dovrebbe andare al database. Quindi come fa il livello del dominio a ottenere le offerte? Tutte le offerte sono state iniettate nel livello dominio dal livello applicazione?

Credo che ci sia uno schema qui che mi manca? Conosco già la Segregazione della Responsabilità dei Comandi. Tuttavia, credo nel mio caso che l'oggetto comando abbia bisogno di accedere al database.

    
posta w0051977 04.07.2017 - 20:07
fonte

2 risposte

12

Se hai bisogno di accedere a un database per risolvere il tuo particolare problema, allora ... Bene, devi accedere a un database. Non importa cosa dicono Jimmy Bogards, Eric Evans o chiunque altro. Se le loro regole non ti permettono di farlo, allora infrangi le loro regole, segui le regole di qualcun altro o creane le tue.

Quando leggi alcune regole su internet che qualcuno ha ideato, cerca di capire le motivazioni che stanno dietro, prima di applicarle. In questo modo, hai una ragionevole sicurezza che l'applicazione di tale regola è in linea con le tue esigenze e aspettative.

Regole come quella che hai citato da Eric Evans generalmente hanno una delle due motivazioni:

  1. Separazione delle preoccupazioni e
  2. Il disaccoppiamento.

Separazione delle preoccupazioni significa principalmente "scrivere ogni classe o metodo in modo che abbia un'area di competenza e funzioni bene". Spesso, ciò significa scrivere un modulo specializzato solo nell'accesso al database, consentendo ad altri moduli / classi di concentrarsi sui propri interessi specifici senza preoccuparsi dei dettagli del recupero dei dati. Significa anche che le tue classi possono essere "persistenti-ignoranti", nel senso che non devono sapere come salvarle o recuperarle da un database, specialmente una tecnologia di database specifica .

Disaccoppiamento, nel contesto dell'accesso al database, generalmente significa una delle due cose:

  1. Vuoi isolare il recupero dei dati dal resto del sistema, nel caso in cui tu possa un giorno modificare l'implementazione del database per qualcos'altro, o
  2. Si vuole prendere in giro il meccanismo di recupero dei dati per scopi di test unitari.

Esistono due modi comunemente accettati per accedere ai dati da un database. Il primo modo è utilizzare le operazioni CRUD (creare, leggere, aggiornare, eliminare). Il secondo è fornire un livello di logica aziendale. Un livello di logica aziendale ha metodi come GetOffers() che fornisce un recupero dei dati più intelligente (e ottimizzato) rispetto a creare, leggere, aggiornare ed eliminare.

Ora quindi. Modelli di dominio malvagio di Jimmy Bogard:

What is a domain model?

An object model of the domain that incorporates both behavior and data.

Why should I care?

A lot of times – you shouldn’t.

When you should – complex domain, or a long-lived project where behavior gets added piece by piece.

Quindi anche Jimmy Bogard dice "usalo solo se ne hai bisogno."

Molti sviluppatori di software oggi soffrono di "malattia Pattern-Matching". Pensano che tutto nello sviluppo del software è un modello e che scrivere un programma è un esercizio di schemi di cucitura insieme. Sfortunatamente, questo non è esattamente il modo in cui funziona, né sta pedissequamente seguendo le idee di qualcuno sulle "migliori pratiche" senza capire il perché.

    
risposta data 04.07.2017 - 22:31
fonte
0

So che questa è una vecchia domanda, ma offrirò una prospettiva diversa.

No.

Non dovresti iniettare il tuo modello di dominio con una IRepository in qualsiasi situazione. Se ti sei trovato in un punto in cui pensi è diventato necessario, ciò che devi fare è dare un'occhiata al design del tuo sistema. È molto più probabile che tu abbia semplicemente fallito nello scriccolare le conoscenze e preso una scorciatoia da qualche parte che non abbia raggiunto i limiti dei principi fondamentali dell'architettura applicativa.

Nell'esempio sopra, mi aspetto che quando viene creato IOfferCalculator (nel gestore comandi), venga iniettato con i dati appropriati in modo che possa prendere le sue decisioni. In un altro modo, invece di iniettare IRepository , si inietta semplicemente i dati che il repository sta per recuperare.

I comandi dell'applicazione sono deterministici. Da qualche parte, qualcosa sa, dato un input, quale dovrebbe essere l'output. Pensa a ogni gestore di comandi come a un processo in 3 fasi (nel tuo livello applicazione):

  1. Recupera TUTTI dati necessari per eseguire il comando.
  2. Coordinate il modello di dominio (stato mutato)
  3. Esegui transazione

In poche parole, è quasi sempre possibile sapere quali dati sono necessari (nel passaggio 1) per coordinare correttamente il dominio (per il passaggio 2). La necessità di recuperare i dati in modo parziale attraverso una transazione può solo creare problemi. Spingi l'accesso ai dati "in alto e in largo" del tuo dominio a cui appartiene. Ciò facilita un design più pulito e più coeso.

Può anche facilitare i test. Ora invece di testare che un mock IRepository restituirà i dati corretti (input forniti) e la tua implementazione di IOfferCalculator , puoi testare direttamente IOfferCalculator rispetto a qualsiasi insieme di dati che desideri. Questo si avvicina al cuore della tua applicazione.

Sono d'accordo con molti dei sentimenti che @RobertHarvey esprime nella loro risposta, ma vorrei strongmente avvertire l'idea di creare le tue regole. Capisco che molti sviluppatori soffrono dell'idea che ogni volta che raggiungono un ostacolo, deve essere che mancano alcuni "pattern" o "principal", ma la realtà è semplicemente che molti sviluppatori non indossano capisco veramente come progettare i sistemi.

Imploro tutti quelli che leggono questo, invece di cercare i dettagli tecnici mancanti in qualche blog (o dovunque) riguardo alla possibilità o meno di iniettare repository (o [inserire qui il problema]), fare un passo indietro e prova a capire il tuo sistema. Figura perché hai raggiunto questa impasse. Spesso, il problema è stato creato da una decisione a monte.

    
risposta data 24.09.2018 - 17:41
fonte

Leggi altre domande sui tag