Come combinare rigoroso TDD e DDD?

10

TDD riguarda la progettazione del codice, guidato dai test.
Pertanto, i livelli tipici non sono di solito costruiti in anticipo; dovrebbero apparire leggermente attraverso i passaggi di refactoring.

La progettazione basata sul dominio coinvolge molti schemi tecnici, definendo livelli ben consolidati come il livello applicazione, il livello infrastruttura, il livello dominio, il livello persistenza.

Per avviare una parte di codifica del progetto DDD da zero, come comportarsi? Devo lasciare che il design emerga dai test, ovvero non c'è separazione tra preoccupazioni (senza livelli) e refactoring per adattarsi ai pattern tecnici del DDD?

O dovrei creare quei livelli vuoti (applicazione, entità / servizi di dominio, infrastruttura) e lasciare che TDD si adatti a ciascuno di essi in modo indipendente (usando i mock per isolare tra i livelli)?

    
posta Mik378 29.05.2016 - 18:29
fonte

4 risposte

7

Assicurati di rivedere i recenti commenti di Uncle Bob sul ruolo di design in TDD .

Domain-driven design involves a lot of technical patterns, defining well established layers like Application layer, Infrastructure layer, Domain Layer, Persistence layer.

Udi Dahan: "Dio, quanto odio la stratificazione". Passa del tempo a discuterne nel suo talk CQRS - ma diverso (la stratificazione inizia a 18m30s)

Scriverò la tua frase in modo leggermente diverso; DDD riconosce che ci sono una serie di preoccupazioni comuni alla maggior parte delle applicazioni aziendali e che le soluzioni a tali preoccupazioni hanno vite diverse.

Ad esempio: le problematiche relative al dominio, di norma, devono essere flessibili, specialmente quando si personalizza una soluzione per un'azienda in particolare. Dopotutto, il dominio riguarda il modo in cui l'azienda fa affari, vale a dire come l'azienda guadagna, e la possibilità di fornire rapidamente miglioramenti aziendali è gratuita.

D'altra parte, probabilmente non è necessario modificare spesso il componente di persistenza. La soluzione di database che ha funzionato nell'ultima versione probabilmente funzionerà anche con questa versione.

I problemi di applicazione sono da qualche parte nel mezzo; tendono ad essere stabili in modo che gli utenti non abbiano bisogno di imparare una nuova app ad ogni rilascio.

Inoltre, ci possono essere più implementazioni per risolvere qualsiasi preoccupazione. Ad esempio, l'applicazione potrebbe necessitare solo di un'istantanea del suo stato corrente: è sufficiente salvare un file su disco. E nelle tue prime iterazioni, potrebbe essere necessario anche tutto il dominio. Ma alla fine arriva una storia che richiede il supporto di query ad hoc e si riconosce che la configurazione di un database relazionale sarà molto più semplice rispetto all'implementazione di uno da zero. E poi c'è questa caratteristica che funzionerebbe meglio in un database grafico.

Nel frattempo, il CTO vuole una versione dell'app che gira sul suo telefono; l'amministratore delegato ha appena sentito da un tizio che pubblicare un'API è la cosa più importante.

Inoltre, il team di vendita utilizza un modello diverso, quindi dacci la stessa app, con un modello diverso. Oh, ma stiamo viaggiando molto, quindi la nostra versione ha bisogno di funzionare quando siamo fuori linea e la sincronizzazione più tardi ....

In altre parole, applichi i modelli tattici da non da implementando segnaposti vuoti e presumendo che verranno inseriti in seguito, ma riconoscendo al momento di attraversare i flussi "Ehi, questo è il codice di persistenza nel mio modello di dominio, non devo ancora fare il refactoring."

    
risposta data 30.05.2016 - 01:45
fonte
7

Test Driven Development (TDD) non è un progetto. È un requisito che influisce sul tuo design. Proprio come se fosse necessario essere thread-safe, non è un design. Ancora una volta, è un requisito che influisce sul tuo design.

Se ignori allegramente tutti gli altri problemi di design e rispetti religiosamente le regole del TDD, non incolpare TDD quando il tuo codice diventa merda. Sarà una merda testabile, ma sarà una schifezza.

Una cosa bella della schifezza testabile è che si tratta di una merda rifattorica, quindi per alcune persone è abbastanza buono. Saremo fantasiosi solo quando necessario. Altri lo odiano e danno la colpa a TDD per questo. No. Questo è il tuo modo di fare.

Domain Driven Design (DDD) è qualcosa che fai prima del ciclo di refattore verde rosso di TDD.

DDD è lo sforzo per creare e conservare uno spazio nel codice in cui un esperto di dominio, che è in gran parte ignaro dei dettagli del sistema, può capire come controllare il sistema. Questo viene fatto tramite l'astrazione e la modellazione di un dominio del problema in un modo familiare.

Un sistema DDD può avere un'architettura simile a questa:

QuestaarchitetturaDDDhamoltinomi: Clean , Cipolla , esagonale , ecc.

Ecco la disconnessione che vedo molte persone quando guardano questo disegno. Questo non è concreto. Posso seguire questo disegno e non aver mai scritto nulla che vedi qui schematizzato. Vedo gli altri insistono che ci deve essere un oggetto caso d'uso o una classe entità. Quello che sono è un insieme di regole che ti dicono con chi puoi parlare e come.

Questo è tutto. Segui le regole di questo design e puoi dare a TDD il tuo piccolo cuore. A TDD non importa a chi parli. Si preoccupa che tutto ciò che fa qualcosa possa essere provato a funzionare o meno con un clic di un pulsante. No, qualcosa da qualche parte è rotto. Ti dice esattamente cosa è rotto.

Ancora a vago? Guarda il diagramma Controler - Use Case Interactor - Presenter nell'angolo in basso a destra. Ecco tre cose concrete che comunicano tra loro. Sicuro che questo è DDD ma come si aggiunge TDD qui? Basta prendere in giro le cose concrete. Il presentatore deve ricevere informazioni. Una classe PresenterMock sarebbe un buon modo per verificare che stia ottenendo ciò che ti aspettavi. Consegnare il Use Case Interactor il PresenterMock e guidare il Use Case Interactor come se fossi il Controller e hai un bel modo di testare l' Use Case Interactor dato che il mock ti dirà se ha ottenuto quello che ti aspettavi ottenere.

Guarda bene. TDD soddisfatto e non abbiamo dovuto rinunciare al nostro design DDD. Come è successo? Abbiamo iniziato con un design ben disaccoppiato.

Se utilizzi TDD per guidare il design (non semplicemente D sviluppo) ottieni un design che riflette lo sforzo che ci metti. Se è quello che vuoi bene. Ma questo non è mai stato concepito per il TDD. Ciò che manca a questo non è certamente colpa di TDD.

TDD non riguarda il design. Se devi apportare modifiche al design per utilizzare TDD, hai problemi più grandi del test.

    
risposta data 30.05.2016 - 01:32
fonte
3

TDD assicura che il tuo codice abbia tutti i casi di test necessari scritti in parallelo allo sviluppo. Questo non dovrebbe influire sul design di alto livello. Pensaci più nel lavoro delle trincee.

DDD si basa su progetti di alto livello, linguaggio tra esperti di dominio e amp; ingegneri, mappatura del contesto, ecc. Questo dovrebbe essere il driver della progettazione ad alto livello dell'applicazione.

Queste sono entrambe spiegazioni superficiali di due potenti metodologie di programmazione. Ma alla fine della giornata realizzano davvero due cose molto diverse.

Inizia con la lingua DDD e amp; la mappatura del contesto quindi alla fine quando si va a scrivere il codice inizia la pratica del TDD. Ma la pratica del TDD non dovrebbe influenzare la progettazione di alto livello, ma dovrebbe assicurare che le cose possano essere testate. Qui c'è un piccolo avvertimento

Penso che potrebbe essere importante notare: si dovrebbe solo praticare DDD se l'applicazione è abbastanza complessa.

    
risposta data 29.05.2016 - 19:56
fonte
2

DDD riguarda la progettazione del software.
TDD riguarda la progettazione del codice.

In DDD, il "modello" rappresenta de astrazione del dominio, tutta la conoscenza da esperto di dominio.

Potremmo usare TDD per il modello di progettazione software iniziale del codice. Il dominio ha regole aziendali e modelli di dominio che il test scritto (primi) dovrebbe essere verde.

In effetti, possiamo codificare i test, dopo aver progettato un modello basato sul dominio.
Questo libro "Software orientato agli oggetti in crescita, guidato dai test" link-for-buy
Adotta questo approccio, con uno scheletro di camminata , architettura esagonale e TDD.

Fonte da: DDD velocemente - InfoQ

    
risposta data 02.04.2018 - 23:43
fonte

Leggi altre domande sui tag