CQRS + Event Sourcing come architettura di primo livello: anti-pattern

3

Ho studiato DDD insieme a CQRS e Event Sourcing. Recentemente ho ascoltato un discorso che Greg Young ha tenuto un paio di anni fa, dove ha affermato che CQRS e Event Sourcing non sono un'architettura di alto livello e dovrebbero essere utilizzati entro i confini di specifici contesti limitati. Fare altrimenti sarebbe un anti-pattern.

Questo ha molto senso in generale, tuttavia sembra essere in conflitto con quello che ho percepito come uno dei vantaggi di un sistema basato su eventi: essere in grado di avere diverse radici aggregate specifiche del contesto della stessa "cosa" in diversi contesti, ciascuno ricostruito dallo stesso flusso di eventi.

Ad esempio un Customer avrebbe un'implementazione diversa in diversi contesti (Ordine, Marketing / Consigli di prodotto, Servizio clienti, Autenticazione), tuttavia alcuni eventi sarebbero rilevanti in più contesti (ad esempio CustomerEmailChanged sarebbe rilevante per il Marketing , Servizio clienti e Autenticazione. OrderPlaced sarebbe rilevante per l'ordine e il marketing).

Prima di ascoltare quel discorso, il mio piano era di condividere questi diversi contesti con un negozio di eventi e ignorare semplicemente eventi che non erano rilevanti. E questo sembra ancora un modo molto ragionevole per gestirlo, ma posso anche vedere come questo potrebbe essere un anti-pattern, sfocando le linee tra i vari contesti limitati.

Quale sarebbe il modo corretto per farlo, oppure il mio approccio è completamente errato?

    
posta Entith 09.07.2018 - 22:21
fonte

3 risposte

4

La ragione per cui ES non è generalmente una buona idea per l'architettura di alto livello ("anti-pattern" non ha più alcun significato reale) è perché è complicato. Chiaro e semplice.

Un sistema ES sta andando a essere più difficile da concettualizzare e sviluppare rispetto a un sistema tradizionale supportato da un RDBMS. Pensaci. Stai essenzialmente aggiungendo un altro livello inferiore (una nuova "verità") alla tua applicazione insieme a tutti gli impianti idraulici necessari per "proiettare" quel livello verso l'alto verso il tuo dominio. Questo non è banale. Non solo perderai probabilmente molti dei vantaggi incorporati che un RDBMS può fornire in termini di vincoli, controllo dei tipi e normalizzazione dei tuoi dati (un archivio eventi di solito è un po 'più libero), devi tenere conto di cose come possibili cambiamenti futuri (versioning) e il mal di testa di modificare "retroattivamente" il tuo negozio di eventi quando ti rendi conto di dover cambiare radicalmente alcuni comportamenti (ti prometto che questo accadrà per qualsiasi sistema non banale). Nel complesso, ES presenta un sistema che è più difficile da capire, più difficile da gestire e più difficile da modificare (potrebbe sembrare un punto di contesa, ma un sistema DDD tradizionale ben progettato è più facile da cambiare. di DDD giusto?).

Dall'altro lato della medaglia, la maggior parte dei vantaggi di ES sono di alto livello (l'introduzione di un altro livello nella tua applicazione non apporta certamente vantaggi agli sviluppatori). Uno dei maggiori vantaggi è che i sistemi ES sono più facili da scalare. Un singolo archivio append-only con modelli di lettura / scrittura separati può essere ridimensionato con facilità. Inoltre, come alluso a @Ewan, poiché il tuo dominio è semplicemente una proiezione dell'archivio degli eventi (ovvero, poiché hai aggiunto un altro livello), i sistemi ES offrono la possibilità di creare facilmente diverse proiezioni dei dati (un nuovo modello di comando può emergere senza dover apportare modifiche allo schema DB, ad esempio). Questo può essere utile per il data warehousing / analisi, ma può anche aiutare a rendere l'applicazione a prova di futuro.

Ora, tenendo presente quanto sopra, possiamo vedere chiaramente che i vantaggi di un sistema ES sono ortogonali ai suoi inconvenienti: benefici di alto livello, svantaggi di basso livello. Ciò è in diretto contrasto con la maggior parte delle altre architetture: DDD si basa sulla creazione di un sistema che è semplice da sviluppare e modificare al costo di eventuali difficoltà nel ridimensionamento, ecc. In genere è un compromesso migliore per i sistemi software perché tendono ad evolversi nel tempo, l'hardware è economico e la maggior parte delle applicazioni semplicemente non richiede una scalabilità / velocità massiccia.

Pertanto, ES dovrebbe applicare quando necessario per aiutare a risolvere un problema / dominio specifico, non ciecamente a un'intera applicazione (i progetti di animali domestici sono esenti).

EDIT - Riguardo alla domanda riguardante "condividere" eventi tra contesti. Ogni contesto deve "possedere" i suoi cambiamenti. Non vuoi un cambiamento in un contesto per creare direttamente un cambiamento in un altro. In questo modo si accoppieranno insieme, il che vanifica l'intero scopo di creare due contesti in primo luogo. Questo è simile al fatto che due aggregati dipendono dallo stesso campo in un RDBMS. Penso che potresti fraintendere il vantaggio che hai delineato riguardo alla ricostruzione di diversi modelli dal tuo flusso di eventi. Questo non si applica ai modelli di comando. È possibile avere UN solo modello di comando per flusso di eventi. Le regole aziendali non possono essere applicate in modo selettivo. E a tal fine, sono possibili più modelli di lettura in qualsiasi sistema.

Più in particolare, chiediti "perché" il tuo evento EmailChanged è pertinente a più di un contesto. Potrebbe essere possibile che tu non abbia diviso i tuoi contesti in modo appropriato? Sembra che tu abbia creato contesti attorno ai confini dell'organizzazione. Questo spesso crea problemi. Ecco una breve discussione sull'argomento:

link

È importante capire che le tue entità e i contesti limitati saranno spesso "scoperti", non decisi in base a una conoscenza olistica della tua attività. Modello in base al comportamento!

    
risposta data 10.07.2018 - 19:04
fonte
0

Il tuo approccio è difettoso.

Considera una regola aziendale per il "contesto di vendita"

If a customer changes their email, they are credited £10

Il "contesto di vendita" Il cliente applica questo credito quando l'email è impostata e si ricostituisce correttamente dall'evento EmailChanged

Il cliente 'contesto account' tuttavia sta ignorando gli eventi EmailChanged. Quando è stato programmato, la regola del £ 10 non era stata inventata. Quindi non cambia e il saldo del cliente non è corretto quando viene visualizzato dall'applicazione per gli account.

Compilando due oggetti distinti dagli eventi che stai facendo esattamente. Non hai due "viste" dello stesso Cliente che hai due clienti dell'universo alternativo. Ogni aspetto come se esistesse solo un sottoinsieme delle regole aziendali.

Modifica: riassunto della discussione dei commenti

Sembra che il tuo punto di vista sia che gli eventi dovrebbero sempre fare una sola cosa quando vengono applicati a un oggetto, aggiornando una proprietà al valore memorizzato nell'evento.

Se qualcosa fa più di una cosa, è un comando e può generare più eventi. cioè EmailChanged, AccountIncremented

Il mio punto di vista è che manca una grossa fetta di Event Sourcing, ovvero che la funzione che applica un evento a un modello può essere qualsiasi cosa tu voglia. Quando un evento EmailChanged viene applicato a un cliente, lasciando da parte l'esempio di account impegnativo relativo ai limiti di dominio, potresti:

  • elimina gli spazi dalla fine dell'indirizzo
  • dividi l'indirizzo in nome utente e dominio
  • aggiungi il vecchio indirizzo a un elenco di vecchi indirizzi email
  • imposta o reimposta un flag InvaildEmail

Si noti che queste sono tutte modifiche interne all'oggetto Cliente. Non generano nuovi eventi e se lo facessero sarebbe problematico.

Il difetto nell'approccio per ignorare gli eventi è che si presume che un evento sia limitato a un dominio e non possa mai avere un effetto di dominio incrociato.

Sì, un buon design suggerisce che se si modifica un indirizzo email accredita l'account cliente, allora dovrebbe attivare un evento External AccountCredit che viene passato al dominio dell'account come nel esempio di comando.

Ma poi ho scelto un esempio ovvio. Chi deve dire che non c'è un errore più sottile, forse c'è un controllo di frode extra quando il flag InvalidEmail è impostato per esempio

    
risposta data 09.07.2018 - 23:22
fonte
0

Sì, all'inizio soffrirai un po 'di dolore, ma non una frazione del dolore cumulativo che dovrai sopportare mantenendo un monolito UN-SOLID che diventa sempre più complesso.

CQRS e Event Sourcing sono l'implementazione più naturale di modelli di business non banali. Pensa a TUTTO ciò che accade intorno a te ogni giorno. Niente inizia senza un trigger (comando) e tutto porta a una serie di eventi. L'idea che un modello di dominio sia costituito solo da Classi e Relazioni è una reliquia degli anni '90 quando la persistenza del database era nella sua infanzia.

Se componi i tuoi modelli di Entità, Relazioni, Radici aggregate, Oggetti valore, Comandi ed Eventi, inizia a verificarsi quanto segue:

  1. Ottieni una singola responsabilità maggiore perché il carico di lavoro si diffonde dove dovrebbe essere. (Grande controller gonfiato in MVC chiunque: -)

  2. Quasi la metà dei bug sono causati da oggetti che non si trovano nel loro stato previsto. Dal momento che Event Sourcing rompe le tue classi di mammut e ti porta alla immutabilità, avrai meno bug.

  3. Ottieni un flusso di lavoro semi-decente gratuitamente.

  4. Puoi porre domande complicate sui tuoi dati (quale elemento nel mio negozio viene aggiunto e quindi rimosso di più?)
  5. Ottieni Auditing gratuitamente.
  6. Ottieni ottime prestazioni preparando i tuoi modelli di visualizzazione con Proiezioni.
  7. La manutenibilità a tutto tondo è generalmente migliore.
  8. Il test è più semplice (la configurazione dei dati dei test di integrazione è molto più semplice)

An ES system is going to be more difficult to conceptualize

Al contrario, è molto più intuitivo per i modelli complessi.

Not only will you likely lose many of the built-in benefits

Vuoi sbarazzarti di loro, ti stanno trattenendo dal lato di comando. Sono ancora tuoi amici dal lato Query.

because your domain is simply a projection of the event store

Il tuo negozio di eventi È il tuo modello di dominio, distribuito nel tempo. Le proiezioni sono modelli di visualizzazione, set di dati de-normalizzati che si presentano ai clienti.

    
risposta data 30.10.2018 - 13:54
fonte