Grails - die Verwendung von Service-Layer

8

Ich habe Probleme beim Organisieren meines Codes, wenn ich ein nicht einfaches Domänenobjekt aktualisieren möchte. Das Problem besteht darin, Verantwortlichkeiten für den Controller und die Serviceebene zu trennen.

Nehmen wir genauer an, dass wir einen Domänenklassen-Client haben, der von anderen Domänenklassen wie Adresse usw. abhängt.

In der Ansicht gibt es ein gsp zum Bearbeiten einiger der Eigenschaften des Clients, einschließlich einiger verschachtelter Eigenschaften wie Straße auf der Adresse.

Wenn ich diese Felder aktualisieren möchte, rufe ich die update-Methode auf einem Controller (in diesem Fall dem ClientController) auf.

Ich mag die Funktion, die von den Fehlern einer Domain-Klasse kommt, wenn sie validiert wird. Wie wenn ich in den Controller

schreibe %Vor%

Wenn der Client jetzt Fehler hat, ist es sehr einfach, sie in der Bearbeitungsansicht anzuzeigen.

Aber ich dachte, dass das Aktualisieren, Speichern und Abrufen des Clients von der Datenbank (Client.get (theId)) von der Dienstschicht behandelt werden sollte. In meinem Fall muss ich andere Domänenobjekte (wie die Adresse) aktualisieren oder erstellen, bevor ich den Client aktualisiere.

Eine meiner Fragen lautet also, wie sollte die API für die Service-Schicht aussehen?

%Vor%

In der Literatur haben sie das triviale Beispiel, das Alter einer Person zu aktualisieren. Ihre API besteht also aus der ID der Person und dem neuen Alter. Aber in meinem Fall habe ich etwa zehn Parameter aus der Sicht und sie sind nur eine Teilmenge aller Eigenschaften eines Kunden und ich weiß nicht, welche von denen, die sich geändert haben.

  1. Ich möchte einen Client im Controller haben, den ich validieren und erneut an die Bearbeitungsansicht senden kann, wenn er Validierungsfehler aufweist.
  2. Ich möchte die Datenbankinteraktionen und -transaktionen von der Serviceebene aus behandeln.

Wie kann ich diese kombinieren? Welche Verantwortlichkeiten sollten die verschiedenen Schichten hinsichtlich der Aktualisierung haben? Wie sollte die API der Service-Schicht bezüglich Update aussehen?

Wenn es irgendwo eine gute Referenzimplementierung gibt, würde ich mich freuen, sie zu studieren. Oftmals wird die Serviceebene leider ganz oder teilweise ignoriert.

    
Per-Henrik 12.09.2014, 08:07
quelle

1 Antwort

5

Das fehlende Teil dieses Puzzles ist Befehlsobjekte . Diese Klassen stellen den Vertrag für Ihre API in Ihren Diensten dar und bieten Ihnen die Möglichkeit, eine konkrete Klasse für Ihre Ansichten und für die Validierung einzurichten. Schauen wir uns ein Beispiel an.

Bei einer Domain-Klasse von Client , die als Address und mehrere Phone -Instanzen Ihre Service-Schicht wie folgt aussehen könnte:

%Vor%

Der ClientUpdateCommand sieht ungefähr so ​​aus:

%Vor%

Sie werden feststellen, dass dieses Befehlsobjekt aus anderen Befehlsobjekten besteht und Einschränkungen für die Validierung aufweist. Es mag so aussehen, als würden Sie Ihre Domain-Klassen hier replizieren, aber ich habe festgestellt, dass je komplexer Ihre Anwendung ist, desto mehr Unterschiede zwischen den Domain-Klassen und Ihren Befehlsobjekten auftreten.

Weiter oben ist die Verwendung des Befehlsobjekts innerhalb Ihres Controllers und Ihrer Ansichten. Eine Controller-Methode sieht etwa so aus:

%Vor%

Ich habe viel aus dem Controller heraus gelassen, da ich Sie nicht mit den Details langweilen wollte, sondern zeigen wollte, wie ein Befehlsobjekt die Domäneninstanz ersetzt. In gewisser Weise ist es ein bisschen mehr Arbeit, aber es bewegt Sie völlig weg von der Manipulation der Domain-Klassen und delegiert diese an den Service, den Sie erstellt haben. Sie werden außerdem feststellen, dass das Befehlsobjekt die Domänenklasseninstanz für Ihr Modell für Ihre Ansichten ersetzt. Ich gebe Ihnen keine Beispiele für die GSPs, da sie sich bei der Verwendung von Befehlsobjekten nicht wesentlich ändern.

Ich bin mir sicher, dass ganze Kapitel von Büchern über das Thema geschrieben sein könnten, aber das gibt Ihnen hoffentlich einen Einblick und Sie können sehen, dass die Antwort auf Ihre Frage (n) lautet: Command Objekte.

    
Joshua Moore 12.09.2014 08:46
quelle

Tags und Links