Se è necessario aggiornare più aggregati, i limiti di aggregazione potrebbero essere errati.
Naturalmente, ci possono essere degli scenari in cui è necessario aggiornare più aggregati. Una saga è il modo tipico per affrontare questo. Nota, tuttavia, che stai lavorando oltre i limiti di consistenza qui.
Se hai la necessità di aggiornare più aggregati atomicamente, è molto probabile che devi ripensare ai tuoi limiti.
La tua applicazione di chat è un esempio perfetto per mostrare come questo può essere molto facile (se possibile anche contro-intuitivo a volte), oltre che abbastanza coinvolto.
Confini
Supponiamo che tu abbia un semplice requisito: un utente non può essere nella stessa stanza due volte.
Un'opzione è di rendere Room
il tuo aggragate, al quale puoi applicare comandi come JoinUser
, GrantPrivileges
, PostMessage
, ecc. Il Room
sarà responsabile per far rispettare l'invariant.
Un'altra opzione è avere un Chatter
aggregato (essenzialmente l'utente). Di nuovo, hai comandi come JoinRoom
e Chatter
applica l'invariante.
Il layout che usi dipende da quali altri invarianti vuoi applicare.
-
L'approccio Room
ti consente di specificare le restrizioni tra le azioni nella stessa stanza (ad esempio non più di 20 utenti possono trovarsi in una stanza).
-
L'approccio Chatter
ti consente di specificare le restrizioni del tuo utente, possibilmente per quanto riguarda più stanze (ad esempio, un utente può essere solo in una stanza alla volta).
Sagas
Dove diventa complicato è se vuoi una combinazione di queste restrizioni. Se non riesci a trovare un modo per suddividere i tuoi aggregati di conseguenza (senza creare una sorta di singleton-super-aggregato che comprenda l'intera applicazione), potresti riuscire a risolvere il problema con una saga.
In questo scenario, l'aggiunta del concetto di Session
potrebbe essere la mossa giusta. Dopo aver creato la sessione, la tua saga prova a registrarla con User
e Room
aggregati (e uccide la sessione se uno dei due fallisce).
Vorrei ancora passare un po 'di tempo a cercare di capire se c'è un altro (forse non ovvio) modo di suddividere prima gli aggregati. Ricorda che non devono rispecchiare i tuoi modelli di lettura: se non hai vincoli di coerenza che si applicano a un'intera stanza, potresti non aver bisogno di un Room
di aggregato sul lato comando.