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


13

Ho letto di Domain Driven Design per quasi due anni e ho introdotto con cautela alcuni concetti nel mio lavoro quotidiano o almeno facendo piani su come le cose che faccio regolarmente potrebbero essere fatte all'interno di un Domain Driven Design.

Una conclusione a cui sto iniziando a giungere in particolare in risposta alla lettura di più sulla Sourcing degli eventi e sulla segregazione di responsabilità delle query di comando (CQRS) secondo cui forse gli oggetti di dominio sono destinati a essere utilizzati solo a scopo di scrittura. Per essere più chiari, sembra che ciò che le persone suggeriscono sottilmente in gran parte della documentazione che ho letto che gli oggetti di dominio sono responsabili di eseguire operazioni / calcoli incentrati sul dominio, convalida e quindi sono principalmente lì a fornire una strada per perseverare l'infrastruttura fornita all'interno di un'implementazione del repository. Anche se mi piace il fatto che ciò possa semplificare notevolmente il modello di dominio in quanto elimina la responsabilità di esporre lo stato.

Se è davvero corretto che gli oggetti di dominio debbano principalmente essere usati come oggetti di sola scrittura, ciò solleva alcune domande a cui spero che qualcuno possa rispondere.

  1. Come si eseguono test unitari su un oggetto che ha setter o metodi che modificano lo stato di un oggetto ma che non forniscono un'interfaccia pubblica esteriore per leggere lo stato come i getter di proprietà in C #? Va bene esporre lo stato esclusivamente allo scopo di rendere quell'oggetto testabile?
  2. Come si mostra a un utente i risultati dei calcoli o delle operazioni eseguiti nel dominio senza doverli persistere e quindi estrarre i risultati dall'archivio persistente al di fuori del contesto del dominio? Va bene esporre lo stato al solo scopo di mostrare i risultati.

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

Materiale correlato:

  1. TDD, DDD e incapsulamento

Risposte:


9

Non sono sicuro che esista una risposta "unica vera" per un approccio progettuale che, per essere onesti, è ancora in evoluzione. In primo luogo, DDD e CQRS non sono la stessa cosa, anche se la gente CQRS sembra derivare da un punto di partenza influenzato dal DDD.

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

Forse stai vedendo un po 'di dibattito su se e come gli oggetti di dominio debbano essere modificabili e quale funzione un oggetto di dominio svolge in un sistema nel suo insieme. CQRS suddivide un sistema in percorsi di lettura e scrittura, quindi è ragionevole concludere che non è effettivamente necessario l'accesso in lettura quando si è sul percorso di scrittura. La lettura diventa quindi qualcosa che fai contro gli eventi generati da alcuni oggetti di dominio e consumati (gestiti) da altri. Se torni un po 'indietro nella storia di CQRS, troverai argomenti secondo cui gli oggetti di dominio non dovrebbero avere setter, solo getter e un singolo metodo "gestore". La logica qui è che solo gli eventi che consumano dovrebbero comportare una modifica dello stato e tale modifica è interamente gestita internamente dall'oggetto dominio.

Puoi mostrare i risultati del cambiamento trattandoli come artefatti separati del cambiamento, inserendoli in una struttura persistente separata (ad esempio una tabella) e leggendoli come se stessi leggendo un rapporto sullo stato attuale e storico del sistema . Ad esempio, potresti consumare un evento estraendo i dati che devi leggere e salvandolo in una tabella del database che si associa strettamente a una singola vista (ad esempio una schermata) del tuo sistema.

Se sperimentate questo stile, sappiate che altri programmatori probabilmente non avranno familiarità con questo approccio e che ci sono relativamente pochi (ma interessanti) scenari in cui è giustificabile come approccio progettuale.

Per i test unitari, ci sono un paio di approcci che potrebbero funzionare per te. Il primo, e il più naturale, è verificare che gli eventi che ti aspetti siano generati dagli oggetti del tuo dominio siano corretti. Un oggetto di 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 non siano stati generati altri eventi.

Un altro approccio consiste nell'utilizzare Spie di prova che espongono attributi leggibili sull'oggetto dominio in modo da poter verificare le modifiche di 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 di DDD e l'esplicitazione dei ruoli sono cambiamenti nel modo di pensare di comunicare con il codice. Il CQRS almeno suggerisce che la lettura dei dati e la scrittura dei dati sono operazioni segregabili. Questa intuizione ti porta a pensare in modo molto chiaro a quale ruolo devono essere presentati i dati, quanto hai davvero bisogno, chi lo sta consumando, quanto deve essere fresco, ecc ... Non hai bisogno di un implementazione completa di Event Sourcing per adottare un migliore incapsulamento nella codifica. Puoi iniziare semplicemente concentrandoti sulle operazioni atomiche all'interno del tuo oggetto, approcci "Tell, Don't Ask" alla progettazione dell'interfaccia dell'oggetto,


1
+1 per iniziare con i bit jucy. Inoltre: mordere solo il CQS (saltando la parte "eventi" per ora) potrebbe essere un buon punto di partenza.
cottsak,

1

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

No. CQRS può essere utilizzato insieme a DDD.


Ma la query parte di CQRS riguarda la query di dati che viene utilizzata dal modello di dominio per scrivere le modifiche al modello o può essere utilizzata per eseguire query sui dati per il livello dell'applicazione che potrebbe indicare mostrare i valori all'utente? Ho sentito da alcuni che DDD si occupa di coordinare le modifiche e non dovrebbe essere usato per leggere altro per coordinare le modifiche a un altro oggetto all'interno del modello di dominio. La decisione in un modo o nell'altro significherebbe un modello radicalmente diverso, visto che i dati esposti sugli oggetti di dominio sarebbero limitati se fossero consumati solo nel dominio.
jpierson,

0

I test delle unità del modello di dominio devono verificare che per ogni comando eseguito vengano generati gli eventi di dominio corretti. I tuoi comandi di dominio e gli eventi acquisiti possono essere interrogati per lo stato.

Puoi anche eseguire ToString()l' override dei comandi e degli eventi del tuo dominio per fornire rapporti di stato automatici e leggibili dall'uomo.

Per rispondere alla seconda domanda, per visualizzare i risultati dei comandi è necessario disporre che gli eventi del dominio siano "pubblicati" nel modello di lettura.


Potresti approfondire un po 'se questo si applica ancora quando non stai usando il sourcing di eventi?
jpierson,

1
Senza l'approvvigionamento di eventi forse il mio suggerimento non funzionerà; Non conosco le modalità del tuo codice. Per un oggetto di dominio che idealmente non espone alcuna proprietà, forse è possibile implementare esplicitamente un'interfaccia di test che espone le proprietà che si desidera verificare. Solo il tuo codice di test saprà "trasmettere" tali oggetti di dominio all'interfaccia di test.
Ed James,

Grazie per quel suggerimento. Mi sento un po 'a disagio sull'idea di modificare le mie classi di dominio in modo specifico per la testabilità, ma suppongo che questa potrebbe essere una di quelle aree grigie ancora in Domain Driven Design se vuoi che sia testabile. Un altro pensiero è che se si dovesse esporre stabilizzabilità e testabilità attraverso la stessa interfaccia, almeno si sta introducendo una sola dipendenza dall'infrastruttura anziché due. Cosa ne pensano gli altri?
jpierson,
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.