Repository Pattern: hoe Lazy Load? of, moet ik dit ene Aggregate?

stemmen
66

Ik heb een domein model dat het concept van een editor en een Project heeft.

Een Editor is eigenaar van een aantal van de projecten, en een Project heeft niet alleen een Editor eigenaar, maar ook een aantal Editor leden. Daarom is een Editor heeft ook een aantal joined Projects.

Ik neem een ​​DDD benadering van het modelleren van dit en het gebruik van de Repository patroon voor persistentie. Echter, ik heb niet het patroon goed genoeg nog grok om te bepalen hoe ik dit moet doen.

Ik ervan uit dat Editor en Project potentieel in hetzelfde aggregaat, waarbij de wortel wordt Editor. Daarom kan ik krijgen een Editor en vervolgens op te sommen zijn Projects, en kon vanaf daar opsomming gegeven van de projecten lid Editors.

Echter, als ik alleen toegestaan ​​om de redactie te halen uit mijn repository, niet dit dat ik moet alle projecten uit de repository te laden toen ik de Editor dat eigenaar is van hen te krijgen? En als ik wil lui belasting van de lid Editors, het project moet een verwijzing naar de repository ook?

Als alternatief, als ik het aggregaat te splitsen en hebben een Redacteur repository en een project repository, hoe moet ik omgaan met een transactie over de twee, zoals wanneer een nieuw project wordt toegevoegd aan een Editor? Bijvoorbeeld:

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

Ben ik een verkeerde interpretatie van de bedoeling van de Repository patroon?

De vraag is gesteld op 19/01/2009 om 15:10
user
In andere talen...                            


4 antwoorden

stemmen
3

Het hangt af van de behoeften van uw applicatie. Als het een groot probleem om alle projecten voor een bepaalde editor te laden, probeer dan een luie laden patroon als een Virtual Proxy .

Ten aanzien van lui laden van het lid redactie van een Project, als je Virtual Proxy gebruiken, zie ik geen probleem het injecteren van de volmacht met de EditorRepository omdat ik geen rekening met de proxy om een ​​deel van het domein.

Als u splitsing van het Aggregate, kunt u de onderzoeken eenheid van het werk patroon als een oplossing voor atomiciteit. Dit probleem is echter niet uniek voor DDD en ik weet zeker dat er andere oplossingen voor transactionele gedrag.

antwoordde op 23/01/2009 om 01:45
bron van user

stemmen
4

Hoe zit het met het splitsen van de verantwoordelijkheden in een EditorOwner en een EditorMember?

Zonder te weten uw domein, zou ik voorstellen dat ze verschillende verantwoordelijkheden zou moeten - bijvoorbeeld, kan het EditorOwner heel rijk zijn (en de totale wortel zou kunnen zijn), maar het project kan alleen maar een beperkte hoeveelheid over haar leden te leren kennen, zodat EditorMember het object kan zeer licht zijn.

Deze domeinnaam voorwerpen kunnen ook betrekking hebben op gebruikers, maar dat zou in een andere context.

Betekent dat dingen helpen, of gewoon maken het ingewikkeld?

antwoordde op 23/01/2009 om 03:55
bron van user

stemmen
0

Hier heb je 2 verschillende relaties, een voor ownership en een voor het lidmaatschap.

De eigendom relatie is eenvoudig voor veel (één eigenaar per project). Het lidmaatschap relatie is many to many (veel Editors per project, veel projecten door editor).

Je kan een eigenaar woning op de class Project bieden, en zorgen voor een methode op ProjectRepository alle projecten die eigendom zijn van een bepaalde editor te krijgen.

Voor de vele relatie, zorgen voor een Leden eigenschap van de klasse Project, en een methode op ProjectRepository om alle projecten die gespecificeerd Editor als lid te krijgen.

Het lijkt er ook op dat Editors en projecten zijn entiteiten, zou ik waarschijnlijk splitsing van de totale, maar misschien deze termen hebben een specifieke betekenis in de context die het subentities van een aggregaat.

antwoordde op 11/02/2009 om 12:01
bron van user

stemmen
30

Ben ik een verkeerde interpretatie van de bedoeling van de Repository patroon?

Ik ga om te zeggen "ja", maar weet dat ik en iedereen die ik heb gewerkt heeft hetzelfde gevraagd om dezelfde reden ... "Je denkt niet 4de dimensionaal, Marty".

Laten we vereenvoudigen het een beetje en de stok met constructeurs methoden in plaats van eerst aanmaken:

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

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

Daaronder wordt uw project repository altijd het opslaan van een geldig eigenaar ( p.EditorId) in het project gegevens als het is gemaakt en hoe je opnieuw bevolken projecten een editor, zal het er zijn. Dit is de reden waarom het is een goede gewoonte om alle vereiste eigenschappen in constructeurs zetten. Als u niet wilt dat het hele object passeren, alleen het e.Idzal doen.

En als ik wil lui belasting van de lid Editors, het project moet een verwijzing naar de repository ook?

Nu, over hoe om te herbevolken projecten een editor's on demand, heb je een paar keuzes, afhankelijk van wat je gaat voor. Straight Repository zegt dat u wilt:

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

Maar waar deze te plaatsen? Niet binnen Project, of Editor, je hebt gelijk, of ze zullen hebben om de toegang tot repositories te krijgen en dat is niet goed. Het bovenstaande fragment is losjes gekoppeld, maar is niet herbruikbaar op zijn eigen. Je hebt net de grenzen van de Repository Pattern bereikt.

De volgende activiteit is een adapter Layer voor uw toepassing, met een gedeelde bron van repositories ( StaticServiceWrapper) en ofwel een soort van EditorAdapter object (of aggregaat of hoe je ze ook wilt noemen) of nu je kunt mixen in extension methods die elk kunnen praten en alle noodzakelijke repositories vloeiend. Ik heb het niet precies gedaan op deze manier in een productie-systeem, maar om te laten zien een beknopt voorbeeld:

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);
    }
}

Kortom, zodra uw GetAll, GetById, toevoegen, updaten, verwijderen objectopslagruimte wordt gedaan, je hebt om de associaties met rust te laten en verder te gaan op het object / laaghiërarchie om het plezier onderdelen zoals adapters en caches en Business Logic ( "Oh , my!" ).

antwoordde op 14/05/2009 om 03:40
bron van user

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