Repository-Muster: wie Lazy Load? oder, sollte geteilt ich dieses Aggregat?

stimmen
66

Ich habe ein Domain-Modell, das das Konzept eines Editor und ein Projekt.

Ein Editor besitzt eine Reihe von Projekten, und ein Projekt hat nicht nur einen Editor Besitzer, sondern auch eine Reihe von Editor Mitgliedern. Daher hat ein Editor auch eine Reihe von „verbunden“ Projekten.

Ich nehme einen DDD Ansatz, dies zu modellieren und das Repository-Muster für die Persistenz verwendet wird. Aber ich grok das Muster nicht gut genug, um noch zu bestimmen, wie ich sollte dies tun.

Ich arbeite auf der Annahme, dass Editor und Projekt ist potenziell in dem gleichen Aggregate, mit der Wurzel zu sein Editor. Ich kann daher einen Editor und dann seine Projekte aufzählen, und von dort konnte der Projekte Mitglied Editors aufzuzählen.

wenn ich jedoch nur, ich darf Redakteure aus meinem Repository abrufen, nicht das, dass ich aus dem Repository alle Projekte zu laden, wenn ich den Editor bekommen, die sie besitzt? Und wenn ich die Mitglied Redakteure zu faul Last will, muss das Projekt eine Referenz als auch auf das Repository?

Alternativ kann, wenn ich das Aggregat geteilt und eine Editor-Repository und eine Projekt-Repository, wie soll ich umgehen, eine Transaktion über die beide, wie wenn ein neues Projekt zu einem Editor hinzugefügt wird? Beispielsweise:

Editor e = new Editor(Editor Name);
editorRepository.Add(e);

Project p = e.CreateProject(Project Name);
projectRepository.Add(p);    // These two lines
editorRepository.Save(e);    // should be atomic

Bin ich falsch interpretiert die Absicht des Repository-Muster?

Veröffentlicht am 19/01/2009 um 15:10
vom benutzer
In anderen Sprachen...                            


4 antworten

stimmen
3

Es hängt von den Anforderungen Ihrer Anwendung. Wenn es ein großes Problem ist , alle Projekte für einen bestimmten Editor zu laden, versuchen Sie dann ein verzögertes Laden Muster wie eine virtuelle Proxy .

In Bezug auf die lazily Mitglied Redakteure eines Projekts laden, wenn Sie Virtual Proxy verwenden, sehe ich kein Problem, den Proxy mit dem EditorRepository Injektion, da ich die Proxy nicht berücksichtigen Teil der Domäne sein.

Wenn Sie die Aggregate aufteilen, können Sie die Untersuchung der Arbeitseinheit Muster als eine Lösung für die Unteilbarkeit. Dieses Problem ist jedoch, nicht eindeutig zu DDD und ich bin sicher , es gibt andere Lösungen für Transaktionsverhalten.

Beantwortet am 23/01/2009 um 01:45
quelle vom benutzer

stimmen
4

Wie wäre es Verantwortlichkeiten in eine EditorOwner und einer EditorMember Aufspaltung?

Ohne Ihre Domain zu wissen, könnte mir vorstellen, ich sie unterschiedliche Aufgaben haben würde - zum Beispiel könnte die EditorOwner ziemlich reich sein (und könnte das Aggregat root sein), aber das Projekt kann nur eine begrenzte Menge über ihre Mitglieder wissen müssen, so das EditorMember Objekt kann ganz leicht sein.

Diese Domain-Objekte können auch Benutzer beziehen, aber das wäre in einem anderen Kontext sein.

Hilft, dass die Dinge, oder einfach nur machen es komplizierter?

Beantwortet am 23/01/2009 um 03:55
quelle vom benutzer

stimmen
0

Hier haben Sie zwei unterschiedliche Beziehungen, einen für Eigentums- und einen für die Mitgliedschaft.

Die Eigentümerbeziehung ist einfach zu viele (ein Besitzer für jedes Projekt). Die Mitgliedschaft Beziehung ist viele, viele (viele Redakteure von Projekt, viele Projekte von der Redaktion).

Sie könnten eine Owner-Eigenschaft auf der Projektklasse, und ein Verfahren auf der ProjectRepository bieten alle Projekte, die von einem bestimmten Editor Besitz zu bekommen.

Für die Beziehung, bieten eine Mitglieder-Eigenschaft auf dem Projektklasse und ein Verfahren auf der ProjectRepository alle Projekte zu bekommen angegebenen Editor als Mitglied enthält.

Es scheint auch, dass Redakteure und Projekte Einheiten sind, würde ich wahrscheinlich das Aggregat gespalten, aber vielleicht diese Begriffe haben eine bestimmte Bedeutung in Ihrem Zusammenhang, dass es aus einem Aggregate machen Sub-Entitäten.

Beantwortet am 11/02/2009 um 12:01
quelle vom benutzer

stimmen
30

Bin ich falsch interpretiert die Absicht des Repository-Muster?

Ich werde „ja“ sagen, aber wissen , dass Sie mich und jede Person , die ich gearbeitet habe hat die gleiche Sache aus dem gleichen Grund gefragt ... „Du bist nicht der 4. dimensions, Marty“ denken.

Sagen wir es ein wenig vereinfachen und halten mit Konstrukteuren statt Methoden erstellen zuerst:

Editor e = new Editor("Editor Name");
e = editorRepository.Add(e);

Project p = new Project("Project Name", e);
p = projectRepository.Add(p);

Darunter wird Ihr Projekt - Repository immer einen gültigen Eigentümer Speichern ( p.EditorId) in die Projektdaten wie es erstellt, und wie Sie einen Editor Projekte neu bevölkern , wird es dort sein. Aus diesem Grunde ist es eine gute Praxis , alle erforderlichen Eigenschaften in Konstrukteure zu setzen. Wenn Sie nicht das ganze Objekt übergeben wollen, nur das e.Idtun wird.

Und wenn ich die Mitglied Redakteure zu faul Last will, muss das Projekt eine Referenz als auch auf das Repository?

Nun, wie ein Projekt des Editors bei Bedarf wieder zu füllen, haben Sie ein paar Möglichkeiten, je nachdem, was Sie gingen für. Gerade Repository sagt, Sie wollen:

IEnumerable<Project> list = projectRepository.GetAllProjects()
                                .Where(x => x.editorId == e.Id);

Aber wohin damit? Nicht innerhalb Project oder Editor, du hast Recht, oder sie müssen den Zugriff auf Repositories erhalten und das ist nicht gut. Die obige Snippet ist lose gekoppelt, aber nicht wiederverwendbar ist auf seinem eigenen. Sie haben gerade die Grenzen des Repository-Muster erreicht.

Als nächstes ist ein Adapter - Layer für Ihre Anwendung, mit einer gemeinsamen Quelle von Endlagern ( StaticServiceWrapper) und entweder eine Art EditorAdapter Objekt (oder Aggregaten oder was auch immer Sie sie nennen würden) oder jetzt können Sie in Erweiterungsmethoden mischen , die zu einem sprechen kann und alle erforderlichen Repositorys fließend. Ich habe es nicht genau diese Art und Weise in einem Produktionssystem getan, aber Ihnen ein prägnantes Beispiel zeigen:

public static class Aggregators
{
    // one to one, easy
    public static Editor GetOwner(this Project p)
    {
        return StaticServiceWrapper.editorRep.GetEditorById(p.editorId);
    }

    // one to many, medium
    public static IEnumerable<Project> GetProjects(this Editor e) 
    { 
        return StaticServiceWrapper.projectRep.GetAllProjects()
                .Where(x => x.editorId == e.Id);
    }

    // many to many, harder
    public static IEnumerable<Editor> GetMembers(this Project p)
    {
        var list = StaticServiceWrapper.projectMemberMap.GetAllMemberMaps()
                        .Where(x => x.projectId == p.projectId);

        foreach ( var item in list )
            yield return StaticServiceWrapper.editorRep.GetEditorById(item.editorId);
    }
}

Im Grunde genommen , wenn Ihr GetAll, GetById, Hinzufügen, Aktualisieren, Entfernen Object Repository getan wird, haben Sie die Verbände alleine und ziehen weiter nach oben Objekt / Layer - Hierarchie auf den Spaß Teile wie Adapter und Cache - Speicher und Business - Logik (verlassen „Oh , mein!“ ).

Beantwortet am 14/05/2009 um 03:40
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more