Sebbene CQRS possa certamente essere usato per questo, ciò per cui è stato sviluppato non è necessariamente un pubblico diverso con requisiti di utilizzo diversi (lettura e scrittura), ma piuttosto per il ridimensionamento del carico.
Separando le capacità di lettura / interrogazione dalle capacità di scrittura / comando, consente all'architettura sottostante una grande flessibilità.
In definitiva questa flessibilità consente due distinte implementazioni parallele, una ottimizzata per la scrittura / aggiornamento e l'altra ottimizzata per la lettura / query.
Il percorso di scrittura può essere implementato utilizzando un archivio relazionale poiché i dati normalizzati sono spesso molto utili per gli aggiornamenti transazionali.
Mentre il percorso di lettura può utilizzare un archivio denormalizzato (relazionale o non relazionale) perché pre-espandendo i join (attraverso la denormalizzazione) di query molto utilizzate, le query possono essere più semplici e più veloci.
Il processo di creazione degli eventi si basa su quel modello, utilizzando un database in stile log di solo accento degli eventi di comando come meccanismo di persistenza primario. Potrebbe esserci ancora un archivio di scrittura normalizzato, ma con ES, questo può fallire e essere ricostruito usando solo gli eventi facili da persistere.
La separazione dell'interfaccia incoraggiata da CQRS è utile se è necessario seguire il percorso delle implementazioni parallele ottimizzate per doppio scopo per la scala.
Tuttavia, questa è una cosa abbastanza complessa. Le implementazioni parallele devono essere sincronizzate l'una con l'altra e atomicamente come osservate da lettori e scrittori, a meno che non si abbiano alcune prove per credere che la propria applicazione funzioni in modo stabile quando vede uno stato temporaneamente incoerente. Ciò significa che, dal momento che il meccanismo di sincronizzazione sta aggiornando l'archivio denormalizzato per ogni dato aggiornamento sul lato di scrittura, dovrebbe mostrare ai consumatori risultati di query solo risultati che includono aggiornamenti denormalizzati completi e non parziali in corso.
In teoria, è possibile separare le interfacce e non aggiungere immediatamente la complessità delle implementazioni duali collegate ma separate.
Tuttavia, per separare veramente la query dai comandi, i comandi devono essere inviati solo con praticamente nessuna risposta dal server. Pertanto, in CQRS spesso troviamo client che emettono la chiave primaria per un'entità appena inviata, piuttosto che il server. Ciò aggiunge una complessità anche senza utilizzare le implementazioni di data store collegate e parallele.
Sarebbe difficile garantire che tu abbia mantenuto le interfacce al modello CQRS se stai usando un solo archivio condiviso poiché credo che ci sarebbe la costante tentazione di restituire valori da un comando a meno che non venga applicato un alto grado di rigore .
Parte della complessità coinvolta viene reinserita nel client che non solo deve fornire le chiavi primarie per le nuove entità, ma deve anche attendere essenzialmente che le modifiche asincrone leggano i risultati dei propri aggiornamenti. Tutto ciò si aggiunge alla complessità che richiede alcune soluzioni non necessariamente disponibili immediatamente disponibili.