Eventi o servizi di dominio per raggiungere la coerenza del modello di dominio?

0

Recentemente ho iniziato ad implementare eventi di dominio nel mio livello di dominio che mi consente di disaccoppiare l'applicazione dal dominio. Alla fine, mi piacerebbe avere un'infrastruttura CQRS con l'infrastruttura di sourcing completo.

La domanda che ho è che ho una classe Account e uno dei casi d'uso è poterlo rinominare. Tuttavia, esiste un vincolo di dominio che dice "nessun account può avere lo stesso nome". Sulla base del mio progetto rapido, presumo che ciò dovrebbe essere implementato con un servizio di dominio che controlla se il nome dell'account è già stato preso e, in caso contrario, rinominare l'account. Ho pensato che potrei allontanarmi da un servizio di dominio utilizzando gli eventi di dominio, ma tutti i gestori di eventi del mio dominio risiedono nel livello applicazione (non nel livello dominio). Ovviamente non voglio avere alcuna logica di business nel livello applicazione.

Sto capendo correttamente la differenza tra servizi di dominio ed eventi di dominio? Mi sembra (basato su quello che ho letto) che gli eventi di dominio ti consentano di separare il livello dell'applicazione dal livello del dominio, ma quando si tratta di garantire la coerenza tra più aggregati, ho bisogno di utilizzare i servizi di dominio. Oppure è possibile farlo con eventi di dominio e mantenere tutto isolato sul livello del dominio? La mia classe Account assomiglia a:

public class Account
{
    public string Name { get; private set; }

    public Account(string name) { // blah // }

    public void AddSubAccount(Account subAccount)
    {
        // do work
    }

    public void RemoveSubAccount(Account subAccount)
    {
        // do work
    }

    public void Rename(string newName)
    {
        Name = newName;
        // How to ensure domain model invariants remain true?
        // No two accounts can have same name
        // Domain Event example:
        // DomainEvents.Publish(new AccountRenamedEvent(oldName, newName));
    }
}
    
posta keelerjr12 06.10.2018 - 14:39
fonte

1 risposta

3

no two accounts can have the same name

Quindi questa è un'espressione di un vincolo noto come Set Validation . La versione breve è che hai due scelte: accetti il fatto che il vincolo non regge sempre e organizza i tuoi processi per rilevare e compensare i conflitti; blocca l'intero set quando esegui una modifica soggetta al vincolo.

Ad esempio, tradizionalmente potremmo averlo modellato come entità Conto e utilizzato un RDBMS transazionale con un vincolo univoco sulla tabella. Il database serializza ogni aggiornamento effettuato su di esso, quindi il vincolo può essere verificato sull'intero insieme di entità account. La meccanica della transazione funge da blocco effettivo dell'intero insieme di voci.

Pensa a cosa succede se ora provi a distribuire questi account tra i database due , mantenendo il vincolo.

Greg Young l'ha davvero inchiodato quando ha introdotto questa domanda nel mix

What is the business impact of having a failure?

Non c'è magia; solo trade off.

It seems to me (based on what I've read) is that domain events allow you to decouple the application layer from the domain layer, but when it comes to ensuring consistency between multiple aggregates, I need to use domain services. Or is this possible to do it with domain events and keep everything isolated to the domain layer?

Il servizio di dominio è l'idea giusta, ma non è sufficiente da solo.

Vale a dire, per il tuo caso d'uso, il codice account rinominato non avrà una copia locale di tutti i nomi limitati, quindi passare un servizio di dominio con la capacità di eseguire il controllo di unicità è un progetto pulito.

Ma il servizio di dominio funziona con le vecchie informazioni; non può rispondere alla domanda "è questo nuovo nome univoco", ma solo una versione più debole "questo nome si scontrerà con quelli che erano in uso 10 nanosecondi fa" o qualsiasi altra cosa. Se i dati sottostanti sono soggetti a modifiche tra quando si pone la domanda e quando si utilizza la risposta, si ha una condizione di competizione e la possibilità di errore.

Per eliminare la condizione di gara, devi avere un certo sapore di blocco che ti protegge da modifiche simultanee.

Ad esempio, il team LMAX ha esaminato la sua architettura e ha compreso che l'unico scrittore avrebbe risolto i loro problemi. Eliminare le scritture concorrenti equivale a bloccare tutti i dati e il sistema può quindi sapere che la risposta non è cambiata mentre la domanda era in volo.

Oggi vedete scelte simili fatte con i sistemi di consenso - un certo numero di componenti distribuiti elegge un leader, e solo a quel leader è permesso di proporre modifiche al flusso di dati, e il leader assicura che proponga solo modifiche coerenti con la storia precedente .

Domain Events should really only be used for what then?

Fowler : cattura la memoria di qualcosa di interessante che influenza il dominio

Eric Evans su Eventi di dominio .

Come schema, sono messaggi che descrivono un cambiamento, consentendo in questo modo di disaccoppiare il calcolo di un cambiamento dalle sue conseguenze.

Tra le altre conseguenze, puoi rileggere l'evento del dominio senza ripetere la modifica; che può essere molto utile in un sistema distribuito su una rete inaffidabile .

    
risposta data 06.10.2018 - 15:54
fonte

Leggi altre domande sui tag