La creazione di una AR causa la creazione di un'altra AR

3

In DDD, va bene se la creazione di una AR forza la creazione di un'altra AR? Prendi ad esempio:

class User
{
  // User related functins
}

class Schedule
{
  // Schedule related functions
}

class Scheduler
{
  private ScheduleRepository repo; // injected

  public void Schedule(User user, Event event)
  {
    Schedule schedule = repo.FindByUser(user);
    schedule.Add(event);
    repo.Save(schedule);
  }
}

Esiste una mappatura 1: 1 tra utente e programma. Quando un utente viene creato devono avere un programma. Non riesco a capire perché un programma esisterebbe senza un utente. Inoltre, quando un utente viene rimosso dal roster / database, desidero che la loro vecchia pianificazione rimanga nel database di pianificazione.

L'oggetto Utente non avrà un riferimento alla loro pianificazione effettiva. Dovresti utilizzare l'oggetto Scheduler per pianificare effettivamente l'evento. L'utente avrebbe un ID privato e numerose proprietà di identità come "Nome", "Email", ecc.

Sono sopraffatto da questo? Inoltre, quando viene creato un utente, suppongo che avrei bisogno di interrogare il UserRepository per ottenere l'ID (PK?) Da associare all'oggetto Schedule.

    
posta keelerjr12 22.01.2018 - 17:07
fonte

2 risposte

4

I pattern di creazione sono strani ....

In DDD, is it okay if creation of one AR forces creation of another AR?

"Dipende", che è parte del problema.

Gli aggregati, come descritto nel libro blu di Evan, sono limiti di coerenza ; si utilizza la radice aggregata per manipolare lo stato incapsulato all'interno di quel confine e quindi assicurarsi che sia sempre in uno stato di coerenza.

Funziona alla grande se sei single threaded.

Quando utilizzi il multithreading, ora hai un ulteriore problema: assicurarti che un thread non esegua il clobber delle scritture fatte in un altro thread. In altre parole, è necessario iniziare a pensare ai limiti transazione e alle corse di dati.

In particolare, se hai una una transazione che tenta di aggiornare gli aggregati che sono archiviati in diverse strutture di persistenza, allora devi preoccuparti di due fasi.

Ciò ha portato un numero di persone a concludere che gli aggregati dovrebbero essere in linea con i confini delle transazioni, il che significa che una modifica a un aggregato non dovrebbe mai consentire di modificare i dati che potrebbero essere memorizzati separatamente.

In effetti, questo spinge l'orchestrazione del (potenziale) commit a due fasi di nuovo nel modello di dominio , dove puoi gestirlo esplicitamente (process manager / sagas). Realizzato in questo modo, i tuoi processi iniziano ad assomigliare più al modello del modello di dominio descritto da Fowler

Immaginate, ad esempio, che UserRepository e ScheduleRepository siano due diversi nelle raccolte di memoria. Scrivi al primo, scrivi al secondo, oops, che ha fallito, cerchi di annullare la scrittura al primo ... che ha già delle modifiche aggiuntive scritte in esso di cui ora devi preoccuparti ...

Quando il tuo archivio di persistenza è un modello relazionale (che era frequente nei primi anni 2000 quando Evans stava scrivendo), puoi usare qualcosa come un pattern di UnitOfWork per gestire la disconnessione - se le due raccolte sono archiviate insieme. È possibile ottenere qualcosa di simile con le collezioni di memoria, se ci si lavora abbastanza, sebbene si abbiano gli stessi problemi di contesa.

Additionally, when a user is removed from the roster/database, I still want their old schedule to persist in the scheduling database.

Potresti voler esaminare il saggio di Udi Dahan Do not Delete - Just Do not

    
risposta data 22.01.2018 - 19:49
fonte
1

In DDD, is it okay if creation of one AR forces creation of another AR?

Sì, è OK. Puoi riscontrarlo quando tenti di applicare SRP agli Aggregati.

Additionally, when a user is removed from the roster/database, I still want their old schedule to persist in the scheduling database.

Questa è un'altra indicazione che hai bisogno di due Aggregati separati.

Tuttavia, tieni presente che, poiché hai due Aggregati, hai un'eventuale coerenza tra loro, questo significa che potrebbe prendersi un po ' prima che il secondo Aggregato sia creato. Un aggregato può garantire solo la sua coerenza.

Poiché @VoiceOfUnreason ha affermato, la creazione del secondo Aggregate potrebbe non riuscire e il tuo sistema non dovrebbe farsi prendere dal panico quando questo succede. Una soluzione per far fronte a questa situazione è quella di modellare la creazione dei due Aggregati come gestore Saga / Process . Questa Saga avrebbe la responsabilità che, alla fine, venga creato il secondo Aggregate (cioè riprovando o notificando un Amministratore per eseguire un'azione).

    
risposta data 23.01.2018 - 08:57
fonte

Leggi altre domande sui tag