Non è l'overengineering CQRS?

11

Ricordo ancora i bei vecchi tempi dei repository. Ma i depositi sono diventati brutti nel tempo. Poi il CQRS è diventato mainstream. Erano gentili, erano una boccata d'aria fresca. Ma recentemente mi sono chiesto ripetutamente perché non mantengo la logica nel metodo Action di un controller (specialmente in Web Api dove l'azione è una sorta di comando / gestore di query in sé).

In precedenza avevo una risposta chiara per questo: lo faccio per i test poiché è difficile testare Controller con tutti quei singleton inammissibili e la brutta infrastruttura ASP.NET. Ma i tempi sono cambiati e le classi di infrastruttura ASP.NET sono molto più facili da test unitari (specialmente in ASP.NET Core).

Ecco una tipica chiamata WebApi: viene aggiunto un comando e i client SignalR ricevono una notifica al riguardo:

public void AddClient(string clientName)
{
    using (var dataContext = new DataContext())
    {
        var client = new Client() { Name = clientName };

        dataContext.Clients.Add(client);

        dataContext.SaveChanges();

        GlobalHost.ConnectionManager.GetHubContext<ClientsHub>().ClientWasAdded(client);
    }
}

Posso facilmente testare l'unità / deriderla. Inoltre, grazie a OWIN posso configurare i server WebApi e SignalR locali e realizzare un test di integrazione (e abbastanza veloce tra l'altro).

Recentemente mi sono sentito sempre meno motivato a creare ingombranti comandi Commands / Queries e tendo a mantenere il codice nelle azioni Web Api. Faccio un'eccezione solo se la logica viene ripetuta o è davvero complicata e voglio isolarla. Ma non sono sicuro se sto facendo la cosa giusta qui.

Qual è l'approccio più ragionevole per la gestione della logica in una tipica applicazione ASP.NET moderna? Quando è ragionevole spostare il codice su Gestori e gestori di query? Ci sono dei modelli migliori?

Aggiornamento. Ho trovato questo articolo sull'approccio DDD-lite. Quindi sembra che il mio approccio nello spostare parti complicate del codice ai comandi / gestori di query possa essere chiamato CQRS-lite.

    
posta SiberianGuy 03.01.2017 - 18:40
fonte

2 risposte

16

CQRS è un modello relativamente complicato e costoso? Sì.

È un eccesso di ingegneria? Assolutamente no.

Nell'articolo in cui Martin Fowler parla di CQRS puoi vedere un sacco di avvertenze sul non utilizzo di CQRS dove è non applicabile:

Like any pattern, CQRS is useful in some places, but not in others.

CQRS is a significant mental leap for all concerned, so shouldn't be tackled unless the benefit is worth the jump.

While I have come across successful uses of CQRS, so far the majority of cases I've run into have not been so good...

Despite these benefits, you should be very cautious about using CQRS.

...adding CQRS to such a system can add significant complexity.

La mia enfasi sopra.

Se la tua applicazione utilizza CQRS per tutto, che non è CQRS eccessivamente ingegnerizzato, è la tua applicazione. Questo è uno schema eccellente per risolvere alcuni problemi specifici, in particolare le applicazioni ad alte prestazioni / volume elevato in cui la concorrenza di scrittura può essere una delle principali preoccupazioni.

E potrebbe non essere l'intera applicazione, ma solo una piccola parte di esso.

Un esempio vivo del mio lavoro, impieghiamo CQRS nel sistema di inserimento ordini, dove non possiamo perdere ordini, e abbiamo picchi in cui migliaia di ordini arrivano contemporaneamente da fonti diverse, in alcune ore specifiche. CQRS ci ha aiutato a mantenere vivo e reattivo il sistema, consentendoci al contempo di scalare bene i sistemi di backend per elaborare questi ordini più rapidamente quando necessario (più server di back-end) e più lento / economico quando non necessario.

CQRS è perfetto per il problema in cui ci sono diversi attori che collaborano nello stesso insieme di dati o scrivono alla stessa risorsa.

Oltre a questo, diffondere un modello creato per risolvere un singolo problema a tutti i tuoi problemi ti creerà solo più problemi.

Altri link utili:

link

link

    
risposta data 03.01.2017 - 19:28
fonte
3

CQRS non è una sostituzione one-for-one per i repository, esattamente perché è un modello complesso e costoso, utile solo in alcuni casi.

Ecco ciò che Udi Dahan ha da dire in merito:

Most people using CQRS (and Event Sourcing too) shouldn’t have done so.

[...]

I’m sorry to say that most sample application you’ll see online that show CQRS are architecturally wrong. I’d also be extremely wary of frameworks that guide you towards an entity-style aggregate root CQRS model.

( source )

Martin Fowler:

[...] you should be very cautious about using CQRS. Many information systems fit well with the notion of an information base that is updated in the same way that it's read, adding CQRS to such a system can add significant complexity.

( fonte )

Infine, Greg Young:

CQRS can be called an architectural pattern.

[...]

This is very important to understand most architectural patterns are not good to apply everywhere. If you see architectural patterns in an architectural guideline you probably have a problem

[...]

The largest failure I see from people using event sourcing is that they try to use it everywhere.

( source )

    
risposta data 04.01.2017 - 13:58
fonte

Leggi altre domande sui tag