CQRS: un po’ di confusione?

Ultimamente si sente sempre più spesso parlare di CQRS ed EventSourcing: ormai se non spari qualche evento su un bus non sei nessuno 🙂

L’intento di questo post è quello di cercare di fare un po’ di chiarezza, per evitare che per risolvere piccoli problemi, se ne creino tanti-e-tanto-grossi.

Innanzitutto partiamo dal primo assunto: CQRS ed ES non viaggiano per forza di pari passo. Applicare CQRS non vincola in alcun modo a, potenzialmente, “sovrastrutturare” la nostra architettura, introducendo code, ESB, messaggi, asincronicità (and so on). Quindi è importante capire che non sempre ho bisogno di tutto.

Ed ora veniamo a CQRS.

Tutto prende spunto da un assunto di Bertrand Mayer, che riporto fedelmente: “Every method should either be a command that performs an action, or a query that returns data to the caller, but NOT BOTH.”

Vi ricorda qualcosa? 🙂

Contestualizzando questa affermazione in ottica DDD ecco la “corretta traduzione” fornita da Greg Young: “A single model cannot be appropriate for reporting, searching and transactional behavior.”

CQRS è un “paradigma” molto semplice che enfatizza alcuni concetti basilari di DDD, che alla sola lettura del libro potrebbero rimanere “sommersi”:

  • il domain model non nasce per collezionare o mostrare dati
  • il domain model deve sempre essere in uno stato consistente
  • i behavior stanno nel modello e non sicurazmente nella UI
  • la UI “potrebbe” non necessariamente avere bisogno di un modello
  • la UI “potrebbe” non avere alcun vantaggio dalla normalizzazione e dall’integrità referenziale

Il domain model è quello “strato” del nostro software che modella i behavior del business e che reagisce ad input esterni, siano essi input dell’utente tramite la UI, input da sistemi terzi, input derivanti da “cambi di stato” del nostro sistema. Non si può e non deve occuparsi di risolvere l’annoso problema delle ricerche, più o meno complesse, che sempre servono agli utenti.

Sembra l’uovo di colombo, ma ci scommetto quello che volete che tutti, almeno una volta nella vita (ma credo anche qualche volta di più), abbiamo commesso l’errore di pensare che un grafo di oggetti, più o meno complesso, potesse essere un domain model, che con l’ORM di turno avremmo risolto tutti i problemi di persistenza e di “caricamento”, pensando che lo stesso modello andasse bene per tutti i gusti, anzi fosse un grosso vantaggio. Bene, ora che abbiamo fatto outing, pensiamo, per esempio, a quanto tempo abbiamo perso speso per ottimizzare query più o meno complesse, perché, con il modello che avevamo a disposizione, non potevamo fare altro che “caricare il mondo” sperando che un po’ di lazy-loading qua e là avrebbe risolto il problema…

Se siamo d’accordo su quanto detto, abbiamo intuito/capito di quali problematiche stiamo parlando, le abbiamo vissute sulla nostra pelle e abbiamo la necessità di limitarle/risolverle.

Ecco in questo caso, forse, CQRS potrebbe fare al caso nostro.

Per ora mi fermerei qua, ricordandovi semplicemente la parte, per me, più importante del famoso libro, il sottotitolo: “Tackling complexity in the heart of  software”. Se non dobbiamo gestire complessità, probabilmente non siamo nel contesto ottimale per “sfruttare” i principi di DDD, non sempre abbiamo bisogno di CQRS, non sempre abbiamo bisogno di un domain model. Usarli per forza è uno degli anti-pattern per eccellenza…