Command Query Responsibility Segregation

Was ist CQRS

Eine CQRS Architekturskizze aus WikipediaDer CQRS Ansatz wurde von Greg Young entwickelt, um die Trennung von Abfragen (Methodenaufrufe, die ausschließlich Informationen liefern – Queries) und Kommandos (Methodenaufrufe, die ausschließlich Änderungen bewirken – Commands) auf komplexe Informationssysteme anzuwenden. Dabei entstehen Systemarchitekturen, die von vielen Kommentatoren als sehr komplex bewertet werden. Der Einsatz wird nur für hochgradig interaktive Informationssysteme mit sehr vielen simultanen Benutzern empfohlen. Einen Eindruck davon vermittelt die nebenstehende Grafik aus Wikipedia.

Wichtige Aspekte von CQRS können unabhängig von der aufwändigen Architektur angewendet werden. Martin Fowler hat dies auf seiner Website gut dargestellt. Die dort skizzierte Architektur, in der Query- und Command-Modelle direkt auf eine Datenbank zugreifen, erscheint etwas zu simpel. Die folgenden Prinzipien lassen sich jedoch gut übernehmen:

  • Eine benutzerzentrierte GUI benötigt unterschiedliche Informationen für jeden Use Case (oder zumindest für eine Gruppe zusammengehörender Use Cases)
  • Diese Informationen sind oft nicht normalisiert und entsprechen nicht den Objekten der Anwendungs-Domain
  • Die dargestellten Informationen unterscheiden sich in der Menge und Struktur meist stark von den Eingaben der Benutzer
  • Deshalb sollten getrennte Klassenmodelle für die Präsentation von Informationen (→ Query-Modell) und für die Benutzereingaben (→ Command-Modell) angelegt werden.

Übertragung auf die Spring-Vaadin-Groovy-Architektur

Die oben genannten Prinzipien lassen sich gut auf den Aufbau der Datentransferobjekte anwenden:

  1. Query-DTOs und Comand-DTOs werden eindeutig voneinander unterschieden.
  2. Für jede verwendete Darstellung (z.B. Tree, Detailtab) werden passende Query-DTOs implementiert.
  3. Für alle Eingaben werden passende Command-DTOs bereitgestellt.
  4. Ein Service Layer aus Spring @Service-Beans bildet die Schnittstelle zum Domain-Modell
    1. Eine Methode einer solchen Service-Bean liefert entweder ein Query-DTO oder nimmt ein Command-DTO entgegen.
    2. Die Konsistenz und Berechtigung von Eingaben wird vom Service sichergestellt.
    3. Service-Klassen können analog zu den DTO-Klassen nach Use Cases oder Anwendungsbereichen strukturiert werden.
  5. Das Service Layer verwendet sowohl die Domain Klassen als auch die (von Spring Data generierten) Repository Beans.
    1. Zur Optimierung können Query-Methoden des Service Layer größere Netze von Objekten direkt über spezielle @Query Methoden der Repository Beans holen.
    2. Alle verändernden Methoden des Service Layer führen die Veränderungen an den Domain Klassen durch, um die Konsistenz zu sichern. Anschließend persistieren sie die geänderten Objekte über Methoden der Repositories.

Die Beispielapplikation lässt sich damit als ein Layer-Modell darstellen: Das untere Layer der Beispielapplikation bilden Domain Klassen und Repositories. Darüber liegt die Uiservice Schicht, ganz oben die View Schicht. DTOs vermitteln den Datentransfer zwischen Uiservice und View.

Das untere Layer der Beispielapplikation bilden domain Klassen und Repositories. Darüber die uiservice Schicht, ganz oben die view Schicht. DTOs vermitteln den Datentransfer zwischen uiservice und View
Layer Anordnung der Pakete

Aufgabe

  1. Identifizieren Sie die neuen Use Cases, die sich aus Ihren Erweiterungen der Anwendungsdomain ergeben.
  2. Modellieren Sie die Informationen aus dem erweiterten Domain Modell, die Sie für die Benutzerschnittstelle brauchen (→ Query Modell).
  3. Modellieren Sie die Befehle und die damit verbundenen Informationen, die durch neue Benutzereingaben auf das erweiterte Domain Modell einwirken (→ Command Modell).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.