2015-02-07 6 views
5

Wenn CQS Befehle daran hindert, Statusvariablen zurückzugeben, wie wird dann für Befehle codiert, die möglicherweise nicht erfolgreich sind? Nehmen wir an, Sie können sich nicht auf Ausnahmen verlassen.Command Query Separation: Befehle müssen void zurückgeben?

Es scheint, als ob alles, was Anfrage/Antwort ist, eine Verletzung von CQS ist.

Es scheint also so, als ob Sie eine Reihe von "mother may I" -Methoden haben würden, die die Status geben, die der Befehl zurückgegeben hätte. Was passiert in einer Multithread-/Multi-Computer-Anwendung?

Wenn drei Clients versuchen, das Objekt eines Servers um eins zu erhöhen (und das Objekt hat die Grenzen 0-100). Alle überprüfen, ob sie es können, aber man bekommt es - und die anderen beiden können nicht, weil es nur ein Limit erreicht hat. Es scheint so, als ob ein zurückgegebener Status das Problem hier lösen würde.

Antwort

4

Es scheint, als ob alles, was Anfrage/Antwort ist, eine Verletzung von CQS ist.

ziemlich ja, also Befehl Abfrage- Trennung. Als Martin Fowler nicely puts it:

Die grundlegende Idee ist, dass wir die Methoden des Objekts in zwei scharf getrennten Kategorien unterteilen sollten:

Abfragen: ein Ergebnis zurück und nicht den beobachtbaren Zustand des Systems ändern (sind frei von Nebenwirkungen).

Befehle: Ändern Sie den Zustand eines Systems, sondern keinen Wert [Hervorhebung von mir] zurückzukehren.

fordert, daß ein Objekt Erhöhung des Servers durch eine ist ein Befehl, so dass es keinen Wert zurückgeben sollte - die Verarbeitung einer Antwort auf diese Anforderung bedeutet, dass Sie einen Befehl und Abfrage-Aktion zur gleichen Zeit tun, die bricht der Grundgedanke von CQS. Wenn Sie wissen möchten, was der Wert des Servers ist, geben Sie eine separate Abfrage.

Wenn Sie wirklich ein Anfrage-Antwort-Muster benötigen, entweder Sie so etwas wie ein gewundener Callback-Ereignis Prozess haben müssen Abfragen für den Status einer bestimmten Anforderung zur Ausgabe oder reinen CQS ist nicht geeignet für diesen Teil Ihr System - notieren Sie das Wort rein.


Multithreading ist ein Hauptnachteil von CQS und kann es schwer machen. Wikipedia hat ein einfaches Beispiel und Diskussion dieses und auch Links zu dem gleichen Martin Fowler Artikel, in dem er vorschlägt, es OK ist das Muster zu brechen, ohne selbst verrückt etwas zu erledigen:

[Bertrand] Meyer [den Erfinder von CQS] verwendet die Befehlsabfragetrennung absolut, aber es gibt Ausnahmen. Das Stapeln eines Stapels ist ein gutes Beispiel für eine Abfrage, die den Status ändert.Meyer sagt richtig, dass man diese Methode vermeiden kann, aber ist ein nützliches Idiom. Also ziehe ich es vor, diesem Prinzip zu folgen, wenn ich kann, aber ich bin bereit, es zu brechen, um meinen Pop zu bekommen.


TL; DR - ich würde wahrscheinlich aussehen nur eine Antwort auf Rückkehr, auch tho es nicht richtig CQS ist.

1

Artikel "Race Conditions Don’t Exist" kann Ihnen helfen, das Problem mit CQS/CQRS Denkweise zu betrachten.

Sie könnten einen Schritt zurückgehen und fragen, warum der Zählerwert vor dem Senden eines Befehls unbedingt erforderlich ist. Anscheinend möchten Sie auf der Client-Seite entscheiden, ob Sie den Zähler mehr erhöhen können oder nicht.

Der Ansatz besteht darin, den Server eine solche Entscheidung treffen zu lassen. Lassen Sie alle Clients Befehle senden (einige werden erfolgreich sein und einige werden fehlschlagen). Schließlich Clients erhalten konsistente Sicht auf den Server-Objektstatus (wo Grenzwert erreicht hat) und können schließlich aufhören, solche Befehle zu senden.

Dieses Zeitfenster der Inkonsistenz führt zu falschen Entscheidungen der Clients, bricht jedoch niemals die Konsistenz des Objekts (oder des Domänenmodells) auf der Serverseite, solange die Befehle angemessen behandelt werden.