Gli oggetti di dominio in Domain Driven Design dovrebbero essere solo di scrittura?

13

Ho letto su Domain Driven Design per quasi due anni e ho introdotto con cautela alcuni concetti nel mio lavoro quotidiano o almeno facendo piani su come fare regolarmente le cose in un Domain Driven Design.

Una conclusione a cui ho iniziato a parlare soprattutto in risposta alla lettura di ulteriori informazioni su Event Sourcing e Command Query Responsibility Segregation (CQRS) che forse gli oggetti di dominio sono destinati ad essere utilizzati solo per scopi di scrittura. Per essere più chiari, sembra che ciò che le persone suggeriscono sottilmente in gran parte della documentazione che ho letto sul fatto che gli oggetti di dominio sono responsabili di operazioni / calcoli, convalida, e quindi ci sono principalmente per fornire una strada alla persistenza attraverso l'infrastruttura fornita all'interno di un'implementazione del repository. Anche se mi piace il fatto che questo possa semplificare notevolmente il modello di dominio in quanto elimina la responsabilità di esporre lo stato.

Se è davvero corretto che gli oggetti di dominio siano principalmente usati come oggetti di sola scrittura, allora sollevo alcune domande per me che spero che qualcuno possa rispondere.

  1. Come si eseguono i test unitari su un oggetto che ha setter, o metodi che modificano lo stato di un oggetto ma che non forniscono alcuna interfaccia pubblica esterna per leggere lo stato da getter di proprietà in C #? Va bene esporre lo stato al solo scopo di rendere tale oggetto verificabile?
  2. Come si può mostrare a un utente i risultati di calcoli o operazioni eseguite nel dominio senza doverli persistere e quindi estrarre i risultati dall'archivio permanente al di fuori del contesto del dominio? Va bene esporre lo stato al solo scopo di mostrare i risultati.

La regola generale è che gli unici getters di proprietà (ottenere accessor) dovrebbero essere quelli che sono anche scrivibili nel dominio? O detto diversamente le proprietà di sola lettura dovrebbero essere l'unica cosa da evitare visto che sono lì solo per scopi di lettura e quindi non svolgono un ruolo necessario nel modello di dominio reale?

Materiale correlato:

  1. TDD, DDD e incapsulamento
posta jpierson 16.12.2011 - 06:28
fonte

3 risposte

9

Non sono sicuro che esista una risposta "un vero modo" per un approccio progettuale che, per essere giusto, è ancora in evoluzione. Innanzitutto, DDD e CQRS non sono la stessa cosa anche se la gente del CQRS sembra derivare da un punto di partenza influenzato dal DDD.

C'è molto da fare nella mentalità DDD e gran parte di esso ha a che fare con confini ben definiti dei problemi, comunicazione tra le parti interessate e interazione tra sistemi, non necessariamente un'implementazione specifica nel codice, quindi non penso di essere troppo duro è una virtù.

Forse stai vedendo alcuni dei dibattiti sul fatto se e come gli oggetti del dominio dovrebbero essere modificabili, e su quale funzione un oggetto dominio serve in un sistema nel suo complesso. CQRS suddivide un sistema in percorsi di lettura e scrittura, quindi è ragionevole concludere che non hai effettivamente bisogno di accesso in lettura quando sei sul percorso di scrittura. Leggere poi diventa qualcosa che fai contro gli eventi generati da alcuni oggetti di dominio e consumati (gestiti) da altri. Se tornerai un po 'nella cronologia di CQRS, troverai argomenti che gli oggetti di dominio non dovrebbero avere setter, solo getter e un unico metodo' gestore '. La logica qui è che solo gli eventi che consumano dovrebbero portare a cambiamenti di stato e che la modifica è interamente gestita internamente dall'oggetto dominio.

Mostrate i risultati del cambiamento trattandoli come artefatti separati del cambiamento, mettendoli in una struttura separata, piatta e persistente (ad es. una tabella) e leggendoli come se steste solo leggendo un rapporto sullo stato corrente e storico del sistema. Ad esempio, puoi consumare un evento estraendo i dati che devi leggere e salvarli in una tabella di database che mappa da vicino una singola vista (ad esempio una schermata) del tuo sistema.

Se si sperimenta questo stile, sii consapevole che altri programmatori probabilmente non conosceranno questo approccio e che ci sono relativamente pochi (ma interessanti) scenari in cui è giustificabile come approccio alla progettazione.

Per i test unitari, ci sono un paio di approcci che potrebbero funzionare per te. Il primo, e più naturale, è verificare che gli eventi che ti aspetti di vedere generati dagli oggetti del tuo dominio siano corretti. Un oggetto dominio potrebbe generare un evento generico modificato contenente informazioni sulla modifica. Potresti verificarlo. È possibile verificare il fatto che l'evento sia stato generato e che gli altri eventi non siano stati generati.

Un altro approccio consiste nell'utilizzare Test Spies che espongono gli attributi leggibili sul tuo oggetto dominio in modo da poter verificare le modifiche dello stato. Ad esempio, puoi ereditare dal tuo oggetto dominio, aggiungere alcuni accessori per leggere quello che altrimenti sarebbe stato incapsulato e verificare che sia corretto.

Ancora una volta, sei confuso perché questi approcci sono confusi. Se stai cercando di adottare alcune buone idee nella tua programmazione, prendi prima i pezzi succosi. I confini del DDD e l'esplicitazione dei ruoli sono cambiamenti nel modo in cui pensi di comunicare con il tuo codice. Il CQRS almeno suggerisce che leggere dati e scrivere dati sono operazioni segregabili. Questa intuizione ti porta a pensare molto chiaramente su quale sia il ruolo dei dati che devi presentare, quanto hai davvero bisogno, chi lo consuma, quanto è fresco, ecc. Non hai bisogno di un implementazione completa di Event Sourcing per adottare una migliore incapsulamento nella codifica. È possibile iniziare concentrandosi solo sulle operazioni atomiche all'interno dell'oggetto, sugli approcci "Dillo, non chiedere" alla progettazione dell'interfaccia dell'oggetto e su Inversion of Control tramite eventi / gestori piuttosto che un controllo rigoroso all'interno dei servizi procedurali.

    
risposta data 15.03.2012 - 17:29
fonte
1

Are Domain Objects in Domain Driven Design only supposed to be write-only?

No. CQRS può essere utilizzato insieme al DDD.

    
risposta data 14.02.2012 - 11:32
fonte
0

I test dell'unità del modello di dominio dovrebbero verificare che per ogni comando eseguito vengano generati gli eventi di dominio corretti. I tuoi comandi di dominio e gli eventi catturati possono essere interrogati per stato.

Potresti anche sovrascrivere ToString() sui comandi e sugli eventi del tuo dominio per fornire un reporting dello stato automatico e leggibile.

Per rispondere alla tua seconda domanda, per visualizzare i risultati dei comandi devi organizzare la pubblicazione degli eventi di dominio sul tuo modello di lettura.

    
risposta data 16.12.2011 - 10:21
fonte