Wie viel Logik sollte ich meinen Repository-Methoden bei der Verwendung von Repository-Muster?

8

Ich kämpfe ein bisschen mit Repositories. Ich benutze C # und NHibernate. Die Frage, die ich habe, ist: Wie viel sollte mein Repository tun, bevor es ein Speichern oder ein Holen aufruft?

Zum Beispiel habe ich eine Benutzerklasse, die eine aggregierte Wurzel ist. Ich möchte eine Methode namens "register" aufrufen, die den Benutzer hinzufügt und einige Standardwerte basierend auf Geschäftsregeln setzt und einige andere Entitäten erstellt, die auch Unterteile des "Benutzer" -Stamms sind (dh Adresse, Gruppen usw.). Soll ich

anrufen? %Vor%

was wäre (ignoriere die offensichtlichen Probleme):

%Vor%

oder sollte ich Register in einer Business-Schicht haben und es tun lassen:

%Vor%

Beide scheinen etwas falsch zu sein.

Was ist der richtige Ansatz?

bearbeiten -------------------------------

Danke für alle Antworten. Ich kann nicht entscheiden, wer am richtigsten ist und daher welche Antwort zu akzeptieren.

Im Allgemeinen sagen alle, dass Sie die Geschäftsregeln in eine andere Ebene einfügen. das macht Sinn, aber ich bin unsicher über die Datenaufrufe für Gruppen - da Gruppen keine aggregierte Wurzel sind, sollten sie kein eigenes Repository haben. Wie gehe ich also vor, sie hinzuzufügen und zu speichern? In meinem Projekt wird beim Hinzufügen einer Gruppe zur Gruppensammlung des Benutzers die Gruppe in der Datenbank nicht automatisch erstellt. Ich muss auch session.save für das Objekt aufrufen. also lege ich das in den Benutzer Repo als userRepo.SaveGroup (g)?

Wenn ich eine createGroup () in der anderen Ebene habe, muss sie entweder ihr eigenes Repo oder die Benutzer verwenden. oder bin ich dick?

    
Charlie Bear 09.06.2009, 16:41
quelle

5 Antworten

3

Bestimmen Sie, wo Sie Ihre Methode registrieren möchten, möglicherweise in einer UserServices-Klasse. Sie können die Objektgenerierung an eine UserFactory delegieren. Legen Sie in einer CreateNewUser () -Methode die Standardwerte für den Benutzer und die Groups-Auflistung fest. Rufen Sie anschließend UserRepository.Save (newUser) auf, um die Daten zu erhalten.

%Vor%     
Kevin Swiber 09.06.2009, 17:07
quelle
6

Persönlich behalte ich das Repository-Muster als Ersatz für Sprocs. Also hätte mein Repository Methoden wie getById(int id) , save() , add(DomainObject obj) etc.

In einer Geschäftsschicht hätte ich userManager.registerUser (string username, / * params, etc * /). Dies würde das Domänenobjekt erstellen. Diese Methode würde nur die Methode add() in der Datenebene aufrufen.

Kurz gesagt, die Geschäftsebene ist geschäftlich und die Datenebene ist Daten-y.

    
Jarrett Meyer 09.06.2009 16:48
quelle
3

Was ist Ihre Motivation, das Repository-Muster überhaupt zu verwenden? Normalerweise ist das Repository die Abstraktion Ihrer Objektpersistenzlogik. Es ruft Elemente von (normalerweise) einer Datenbank ab und behandelt auch Aktualisierungen, Einfügungen und Löschungen.

Wenn Sie einen Test geschrieben haben, um einige Logik zu überprüfen und nicht die Datenbank schlagen wollten, welche Objekte müssten Sie verspotten? Normalerweise das Repository.

In Szenario A) können Sie nicht testen, ob ein neuer Benutzer mit den korrekten Standarddaten erstellt wurde, ohne direkt auf die Datenbank zu treffen. Aus diesem Grund würde ich dafür eintreten, die gesamte Geschäftslogik außerhalb der Repositorys zu belassen und mit Ihrem zweiten Design zu arbeiten.

    
Kirschstein 09.06.2009 17:03
quelle
1

In Ihrem Codebeispiel würde ich die Register-Methode als Serviceoperation aufrufen. Als Serviceoperation würde es eher einem Service oder einer Geschäftskomponente als einem Repository angehören. Laut Evans (von DDD fame) ist ein Repository eine sammlungähnliche Schnittstelle zu Entitäten, die in Ihrer Datenbank gespeichert sind. Die allgemeine Idee ist, dass Sie Ihren Entitäten über ein Repository grundlegenden CRUD-ähnlichen Zugriff gewähren, um den Rest Ihres Codes von Datenzugriffsdetails auf niedrigerer Ebene wie einem ORM-Tool zu abstrahieren.

Für Ihr Beispiel mit Register ... würde Ihre Servicemethode Eingaben validieren, das Benutzerobjekt erstellen und dann Ihr Repository aufrufen, um Ihre neue Entität dem "Repository" hinzuzufügen (was eine Datenbank sein könnte, aber ...) könnte auch etwas anderes sein ... soweit es um Ihre Domain geht, spielt es keine Rolle ... es ist nur ein Repository.)

    
jrista 09.06.2009 17:08
quelle
0

Ich sehe zwei mögliche "Unrichtigkeiten" (da Sie nicht wirklich angegeben haben, was Sie für falsch hielten).

  1. Wenn das Problem darin besteht, die Gruppe in der Benutzerregistrierungsmethode zu speichern oder den Benutzer in den Gruppenmethoden zu speichern, sollten Sie diese in verschiedene Methoden aufteilen. (d. h. Register () würde RegisterGroup () oder GetGroup ()

  2. aufrufen
  3. Wenn das Problem darin besteht, Dinge zu speichern, bevor der Benutzer wirklich bereit ist, Dinge konzeptionell zu speichern, dann behalten Sie den Überblick darüber, was hinzugefügt werden soll, und warten Sie, bis die gesamte "Speicher" -Methode aufgerufen wird, bevor Sie diese Informationen eingeben in den Speicher.

John Fisher 09.06.2009 17:07
quelle