Modellazione di sprint e ticket in DDD

-2

Sto cercando di imparare DDD / CQRS in un progetto di hobby. E non avere precedenti esperienze. In questo progetto utilizzo MongoDb come db di lettura e EventStore come db di scrittura.

Sto costruendo una semplice applicazione 'Sprint board'. (Mi piace JIRA / Asana)

Modello

  • Sprint
  • Biglietti

Ho deciso di modellarlo come due aggregati separati. Perché volevo mantenere i miei aggregati piccoli e mantenere i 'confini transazionali' il più scalabili possibile. (Riferimento: Vaughn Vernon )

Una delle mie funzionalità che vorrei creare in questo sistema è che uno sprint può essere chiuso solo quando ogni ticket è chiuso.

Mi è sembrato un cattivo progetto caricare ogni ticket in memoria al momento di decidere se uno sprint poteva essere chiuso.

Quindi stavo pensando a un sistema in cui uno sprint tiene traccia della quantità di "biglietti creati" e "biglietti chiusi"

  • CreateTicketCommand (from FrontEnd)

    • Crea l'aggregazione del ticket
      • Fires TicketCreatedEvent
  • TicketCreateEvent viene gestito da un ProcessManager

    • Crea un comando AddTicketToSprint
  • Il comando AddedTicketToSprint viene gestito (viene recuperato l'aggregato Sprint)

    • TicketId viene aggiunto in un campo di ticket List nell'aggregato sprint.

il tempo passa ...

  • CloseTicketCommand (from FrontEnd)

    • Recupera aggregazione ticket + evento Fire TicketStatusChanged
  • TicketStatusChanged viene gestito da un ProcessManager

    • Esegue un comando CloseSprintTicket
  • Commandhanlder - > Recupera aggregato sprint

    • Imposta un campo intero 'closedTicketAmount' ++

Ora, quando un oggetto CloseSprintCommand viene attivato da FrontEnd, posso verificare se closedTicketAmount è uguale alla quantità di ticket nella mia lista di ticket. Se così non fosse, non dovrei essere in grado di chiudere lo sprint.

Quindi ho ottenuto ogni logica che volevo. Ma mi sembra un po 'sporco. Che cosa succede se in futuro voglio uno stato 'Archivio' sui miei biglietti. Di quanto dovrei controllare (e così via ...)

if (tickets.Count > closedTicketAmount + archivedTicketAmount)
    throw new ApplicationException("Sprint cannot be closed when not every ticket is closed");

E si ha la sensazione che sia probabilmente più corretto caricare tutti gli aggregati dei biglietti in memoria attraverso un servizio di dominio. Ma non ho idea di quale sia un buon modello per caricare più aggregati contemporaneamente. (Tranne che per foreach(){ _repository.Get(a.Id)} )

Mi piacerebbe sentire l'esperienza di altre persone.

Quindi la mia domanda attuale è: Sto pensando in modo completamente sbagliato? Invitando il mio anti-modello. Dovrei semplicemente smettere di pensare e iniziare a leggere più libri.

A proposito:

Cordialmente, Brecht

    
posta ErazerBrecht 08.03.2018 - 20:48
fonte

1 risposta

1

Ci sono un paio di approcci che faranno il lavoro qui (hai menzionato entrambi), ma sarei restio ad adottare il metodo che stai proponendo - mantenendo un openTicketCount sul tuo Sprint . Ha tutti i presupposti per l'ottimizzazione prematura senza giustificazione al costo di rendere il sistema un po 'più complesso.

Iniziamo parlando della soluzione più semplice possibile: La tua Sprint contiene un riferimento a tutti% di% co_de. Questo risolve il problema (e forse anche più che potrebbe comportare un Tickets che richiede la conoscenza della composizione del suo Sprint ) e semplifica anche il tuo modello di eventi. L'unico inconveniente è che dovrai caricare tutto il Tickets in memoria quando vuoi caricare Tickets . Quanti% diSprint supponi saranno associati a Tickets ? Se il numero non è proibitivamente grande, questo non dovrebbe essere di grande preoccupazione. Per quanto mi riguarda, sembra che troverai altri motivi per caricare comunque tutti Sprint per Tickets .

Se implementato correttamente, dovrebbe essere banale ottimizzare il tuo sistema in un secondo momento per caricare invece Sprint . Lei dice che questo è un progetto per hobby per familiarizzare con DDD. La qualità del design di un sistema è la facilità con cui può essere modificato , quindi non esiste un modo migliore per testare le tue abilità piuttosto che iniziare con un sistema totalmente non ottimizzato e poi vedere quanto bene puoi refactoring più tardi. So che non è il più "divertente", ma ti preparerà per il mondo reale. Il refactoring continuo verso intuizioni più profonde è una pietra miliare del DDD.

Un altro punto che voglio sottolineare qui è che il tuo modello di dominio è scoperto . Non semplicemente deciso in base al numero di contesti limitati che desideri o alle radici di Aggregate che desideri.

    
risposta data 13.03.2018 - 16:14
fonte

Leggi altre domande sui tag