it-swarm.com.de

Ist CQRS nicht Overengineering?

Ich erinnere mich noch an gute alte Zeiten von Repositories. Aber Repositories wurden mit der Zeit immer hässlicher. Dann wurde CQRS zum Mainstream. Sie waren nett, sie waren ein Hauch frischer Luft. Aber in letzter Zeit habe ich mich immer wieder gefragt, warum ich die Logik in der Action-Methode eines Controllers nicht richtig halte (insbesondere in Web Api, wo Action eine Art Befehls-/Abfrage-Handler für sich ist).

Zuvor hatte ich eine klare Antwort darauf: Ich mache es zum Testen, da es schwierig ist, Controller mit all diesen nicht blockierbaren Singletons und der insgesamt hässlichen ASP.NET-Infrastruktur zu testen. Aber die Zeiten haben sich geändert und ASP.NET-Infrastrukturklassen sind heutzutage viel einheitlicher für Unit-Tests (insbesondere in ASP.NET Core).

Hier ist ein typischer WebApi-Aufruf: Befehl wird hinzugefügt und SignalR-Clients werden darüber benachrichtigt:

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);
    }
}

Ich kann es leicht Unit-Test/Mock. Darüber hinaus kann ich dank OWIN lokale WebApi- und SignalR-Server einrichten und einen Integrationstest durchführen (und das übrigens ziemlich schnell).

In letzter Zeit war ich immer weniger motiviert, umständliche Handler für Befehle/Abfragen zu erstellen, und ich neige dazu, Code in Web-API-Aktionen beizubehalten. Ich mache nur dann eine Ausnahme, wenn die Logik wiederholt wird oder sie wirklich kompliziert ist und ich sie isolieren möchte. Aber ich bin mir nicht sicher, ob ich hier das Richtige tue.

Was ist der vernünftigste Ansatz zum Verwalten von Logik in einer typischen modernen ASP.NET-Anwendung? Wann ist es sinnvoll, Ihren Code in die Handler für Befehle und Abfragen zu verschieben? Gibt es bessere Muster?

Update. Ich habe diesen Artikel über den DDD-Lite-Ansatz gefunden. Es scheint also, als könnte mein Ansatz, komplizierte Teile des Codes in Befehls-/Abfrage-Handler zu verschieben, als CQRS-lite bezeichnet werden.

16
SiberianGuy

Ist CQRS ein relativ kompliziertes und kostspieliges Muster? Ja.

Ist es Überentwicklung? Absolut nicht.

Im Originalartikel, in dem Martin Fowler über CQRS spricht sehen Sie viele Warnungen, dass CQRS nicht verwendet wird, wenn es nicht anwendbar ist:

Wie jedes Muster ist CQRS an einigen Stellen nützlich, an anderen jedoch nicht.

CQRS ist ein bedeutender mentaler Sprung für alle Beteiligten, daher sollte nicht angegangen werden, es sei denn, der Nutzen ist den Sprung wert .

Obwohl ich auf erfolgreiche Anwendungen von CQRS gestoßen bin, war die Mehrheit der Fälle, auf die ich gestoßen bin, bisher nicht so gut ...

Trotz dieser Vorteile sollten Sie bei der Verwendung von CQRS sehr vorsichtig sein.

... das Hinzufügen von CQRS zu einem solchen System kann zu einer erheblichen Komplexität führen .

Meine Betonung oben.

Wenn Ihre Anwendung CQRS für alles verwendet, ist CQRS nicht überentwickelt, sondern Ihre Anwendung. Dies ist ein hervorragendes Muster zur Lösung einiger spezifischer Probleme, insbesondere von Anwendungen mit hoher Leistung und hohem Volumen, bei denen die Parallelität beim Schreiben ein Hauptanliegen sein kann.

Und es ist möglicherweise nicht die gesamte Anwendung, sondern nur ein kleiner Teil davon.

Als Live-Beispiel aus meiner Arbeit setzen wir CQRS im Auftragserfassungssystem ein, wo wir keine Aufträge verlieren können, und wir haben Spitzen, bei denen Tausende von Aufträgen gleichzeitig aus bestimmten Quellen in bestimmten Stunden eingehen. CQRS hat uns geholfen, das System am Leben zu erhalten und zu reagieren, und es uns ermöglicht, die Backend-Systeme gut zu skalieren, um diese Bestellungen bei Bedarf schneller zu verarbeiten (mehr Backend-Server) und langsamer/billiger, wenn sie nicht benötigt werden.

CQRS ist perfekt für das Problem geeignet, bei dem mehrere Akteure in demselben Datensatz zusammenarbeiten oder in dieselbe Ressource schreiben.

Abgesehen davon führt die Verbreitung eines Musters zur Lösung eines einzelnen Problems auf alle Ihre Probleme zu mehr Problemen.


Einige andere nützliche Links:

http://udidahan.com/2011/04/22/when-to-avoid-cqrs/

http://codebetter.com/gregyoung/2012/09/09/cqrs-is-not-an-architecture-2/

17
Machado

CQRS ist kein Eins-zu-Eins-Ersatz für Repositorys, gerade weil es sich um ein komplexes, kostspieliges Muster handelt, das nur in einigen Fällen nützlich ist.

Folgendes hat Udi Dahan zu verdanken:

Die meisten Benutzer von CQRS (und auch Event Sourcing) hätten dies nicht tun sollen.

[...]

Es tut mir leid zu sagen, dass die meisten Beispielanwendungen, die Sie online sehen und die zeigen, dass CQRS architektonisch falsch sind. Ich bin auch äußerst vorsichtig mit Frameworks, die Sie zu einem aggregierten Root-CQRS-Modell im Entitätsstil führen.

( Quelle )

Martin Fowler:

[...] Sie sollten bei der Verwendung von CQRS sehr vorsichtig sein. Viele Informationssysteme passen gut zum Begriff einer Informationsbasis, die auf die gleiche Weise aktualisiert wird, wie sie gelesen wird. Das Hinzufügen von CQRS zu einem solchen System kann zu einer erheblichen Komplexität führen.

( Quelle )

Schließlich Greg Young:

CQRS kann als Architekturmuster bezeichnet werden.

[...]

Dies ist sehr wichtig, um zu verstehen, dass die meisten Architekturmuster nicht überall gut anzuwenden sind. Wenn Sie Architekturmuster in einer Architekturrichtlinie sehen, haben Sie wahrscheinlich ein Problem

[...]

Der größte Fehler, den ich bei Leuten sehe, die Event-Sourcing verwenden, ist, dass sie versuchen, es überall zu verwenden.

( Quelle )

4
Sklivvz