Gilt die Trennung von Befehlen und Abfragen für eine Methode, die ein Objekt erstellt und dessen ID zurückgibt?

12

Nehmen wir an, wir haben einen Service, der einen Geschäftsprozess aufruft. Dieser Prozess ruft die Datenschicht auf, um ein Objekt vom Typ A in der Datenbank zu erstellen.

Anschließend müssen wir erneut eine andere Klasse der Datenschicht aufrufen, um eine Instanz des Typs B in der Datenbank zu erstellen. Wir müssen einige Informationen über A für einen Fremdschlüssel übergeben.

In der ersten Methode erstellen wir ein Objekt (Status ändern) und geben dessen ID (Abfrage) in einer einzigen Methode zurück.

In der zweiten Methode haben wir zwei Methoden, eine (createA) für das Speichern und die andere (getId) für die Abfrage.

    public void FirstMethod(Info info)
    {
        var id = firstRepository.createA(info);           
        secondRepository.createB(id);
    }

    public void SecondMethod(Info info)
    {
        firstRepository.createA(info);
        var key = firstRepository.getID(info);
        secondRepository.createB(key);
    }

Nach meinem Verständnis folgt die zweite Methode der Befehlsabfragetrennung vollständiger. Aber ich finde es verschwenderisch und nicht intuitiv, die Datenbank abzufragen, um das Objekt zu erhalten, das wir gerade erstellt haben.

Wie vereinbaren Sie CQS mit einem solchen Szenario?

Folgt nur die zweite Methode CQS, und wenn ja, ist es in diesem Fall vorzuziehen, sie zu verwenden?

Gilles
quelle
2
Wenn A und B zusammen mit einer Frequenz erstellt werden, würde ich wahrscheinlich eine gespeicherte Prozedur beide auf einmal erstellen lassen, und dann schneiden Sie das Potenzial aus, ein B zuerst oder ein A ohne B erstellen zu lassen, wenn dies Probleme sind.
Ryathal
Steigen Sie spät ins Spiel ein, um die Möglichkeit zu haben, einen Out-Parameter zu verwenden. Es ist technisch gesehen kein Rückgabewert! ;)

Antworten:

13

CQS ist eher eine Richtlinie als eine absolute Regel. Im Wiki-Artikel finden Sie Beispiele für Aktivitäten, die unter strengen CQS nicht möglich sind.

In diesem Fall können Sie jedoch, wenn Sie CQS verwalten möchten, entweder die ID auf der Clientseite erstellen (z. B. eine GUID), oder der Client kann eine ID vom System anfordern, bevor Objekte erstellt werden, die sich sauberer anfühlen Ich erstelle das Objekt und frage es dann ab (aber es ist schwieriger, als nur eine Identitätsspalte zu verwenden).

Persönlich würde ich einfach den Ausweis zurückgeben und ihn als eine der Situationen bezeichnen, in denen CQS nicht gut passt.

Ein weiterer guter Artikel mit Beispielen: Martin Fowler

Misko
quelle
3

Wenn Sie einer Methodik folgen und es scheint, als würden Sie schlechte Wege beschreiten, sollten Sie sie neu bewerten.

Ich sehe, dass der Bezeichner eines neu erstellten Objekts ein gültiger Rückgabeparameter ist - er ist nicht nur praktisch, sondern auch "gut" - da Sie sehen, dass Code besser ist, wenn er es tut.

Auf jeden Fall bin ich mit "Trennung von Befehlsabfragen" nicht vertraut, aber ich bezweifle sehr, dass Befehle keine Informationen über die Befehlsausführung zurückgeben dürfen, und wenn dies der Fall ist, verwerfen Sie es einfach - Erfolg / Misserfolg ist immer da, und das tue ich Ich denke nicht, dass "Ihr Objekt wurde OK erstellt" von "Ihr Objekt wurde OK erstellt und seine ID ist xxx", um viel anders zu sein.

Alex
quelle
-1

Nur die zweite Methode folgt auf CQS.

Ich halte CQS für eine Richtlinie zur Förderung guter Codierungspraktiken. Wenden Sie während der Entwicklung bewährte Codierungsmethoden an. Wenn Sie später feststellen, dass diese Methode ressourcenkritischen Code enthält, können Sie ihn dennoch optimieren.

Vorzeitige Optimierung ist die Wurzel allen Übels :)

Cheesus sagt, hör auf, Mods abzufeuern
quelle
Was ist bei der zweiten Methode besonders gut?
CheatEx
Ich habe nicht gesagt, dass die zweite Methode "gut" ist. Ich sagte, es folgt dem CQS-Paradigma. Wenn Sie CQS nicht befolgen, ist die zweite Methode vermutlich nicht gut für Sie. Wenn Sie wissen wollen , warum einige Leute versuchen , CQS zu folgen, sehen http://en.wikipedia.org/wiki/Command-query_separation
cheesus sagt mods Stop Brennen
Sie sagten, dass CQS gute Codierungspraktiken fördert. Wenn dies zutrifft, sollten wir bei der zweiten Methode eine Art "Güte" beobachten. Wo ist es?
CheatEx
Anscheinend haben Sie den von mir angegebenen Link nicht gelesen. CQS-Schlagwort: Das Stellen einer Frage sollte die Antwort nicht ändern . In Ihrer ersten Methode haben Sie eine Methode ('createA'), die eine 'Antwort' liefert, aber die Antwort jedes Mal ändert, wenn Sie danach fragen. Bei der zweiten Methode haben Sie das nicht, das ist die "Güte" darin. Um es klar auszudrücken: Ich bin kein CQS-Purist, ich verfolge es nicht jedes Mal.
Cheesus sagt, hört auf, Mods zu feuern