Pattern Repository: comment charger Lazy? ou, devrais-je diviser cet agrégat?

voix
66

J'ai un modèle de domaine qui a le concept d'un éditeur et un projet.

Un éditeur possède un certain nombre de projets, et un projet a non seulement un propriétaire de l'éditeur, mais aussi un certain nombre de membres de l'éditeur. Par conséquent, un éditeur a aussi un certain nombre de « joints » Projets.

Je prends une approche DDD à la modélisation et ce en utilisant le modèle du référentiel de persistance. Cependant, je ne Grok encore le modèle assez bien pour déterminer comment je devrais le faire.

Je travaille sur l'hypothèse que la rédaction et le projet sont potentiellement dans le même agrégat, la racine étant éditeur. Je ne peux donc obtenir un éditeur, puis énumérer ses projets, et pourrait d'énumérer les rédacteurs là membres de projets.

Cependant, si je ne suis autorisé à récupérer des rédacteurs de mon dépôt, ne pas dire que je dois charger tous les projets du référentiel quand je reçois l'éditeur qui les possède? Et si je veux charger les rédacteurs paresseux membres, le projet a besoin d'une référence au référentiel ainsi?

Sinon, si je diviser l'ensemble et ont un référentiel éditeur et un dépôt de projet, comment dois-je gérer une transaction entre les deux, par exemple quand un nouveau projet est ajouté à un éditeur? Par exemple:

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

Suis-je mal interprété l'intention du motif du référentiel?

Créé 19/01/2009 à 15:10
utilisateur
Dans d'autres langues...                            


4 réponses

voix
3

Cela dépend des besoins de votre application. S'il est un gros problème pour charger tous les projets pour un éditeur donné, essayez un modèle de chargement paresseux comme un proxy virtuel .

En ce qui concerne le chargement paresseusement les membres des rédacteurs d'un projet, si vous utilisez Virtual Proxy, je ne vois pas de problème avec l'injection du proxy du EditorRepository puisque je ne considère pas le proxy pour faire partie du domaine.

Si vous divisez l'agrégat, vous pouvez enquêter sur l' unité de travail modèle comme une solution à atomicité. Ce problème, cependant, est pas unique à DDD et je suis sûr qu'il existe d' autres solutions pour le comportement transactionnel.

Créé 23/01/2009 à 01:45
source utilisateur

voix
4

Que diriez-vous diviser les responsabilités dans un EditorOwner et un EditorMember?

Sans connaître votre domaine, j'imagine qu'ils auraient des responsabilités différentes - par exemple, le EditorOwner pourrait être assez riche (et pourrait être la racine globale), mais le projet ne peut besoin de connaître un nombre limité de ses membres, afin l'objet EditorMember peut être tout à fait clair.

Ces objets de domaine peuvent également concerner les utilisateurs, mais ce serait dans un autre contexte.

Est-ce que les choses aider, ou tout simplement le rendre plus compliqué?

Créé 23/01/2009 à 03:55
source utilisateur

voix
0

Ici, vous avez 2 relations différentes, l'une pour la propriété et un pour l'adhésion.

La relation de propriété est simple à plusieurs (un propriétaire pour chaque projet). La relation d'appartenance est beaucoup à beaucoup (de nombreux éditeurs de projet, de nombreux projets par l'éditeur).

Vous pouvez fournir une propriété du propriétaire sur la classe du projet, et de fournir une méthode sur l'ProjectRepository pour obtenir tous les projets appartenant à un éditeur spécifique.

Pour les nombreuses relations, fournir une propriété des membres de la classe du projet, et une méthode sur l'ProjectRepository pour obtenir tous les projets contenant éditeur spécifié en tant que membre.

Il semble également que les éditeurs et les projets sont des entités, je serais probablement diviser l'ensemble, mais peut-être ces termes ont une signification particulière dans votre contexte qui en font sousentités d'un agrégat.

Créé 11/02/2009 à 12:01
source utilisateur

voix
30

Suis-je mal interprété l'intention du motif du référentiel?

Je vais dire « oui », mais sachez que moi et chaque personne que j'ai travaillé avec a demandé la même chose pour la même raison ... « Tu ne penses pas 4 dimensions, Marty ».

Simplifions un peu et le bâton avec les constructeurs au lieu de créer des méthodes d'abord:

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

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

Au- dessous, votre dépôt de projet est toujours stocker un propriétaire valide ( p.EditorId) dans les données du projet comme il est créé, et cependant vous repeupler les projets d'un éditeur, il sera là. Voilà pourquoi il est une bonne pratique de mettre toutes les propriétés requises dans les constructeurs. Si vous le faites, juste le voulez pas passer tout l'objet e.Idfera.

Et si je veux charger les rédacteurs paresseux membres, le projet a besoin d'une référence au référentiel ainsi?

Maintenant, quant à la façon de repeupler les projets d'un éditeur à la demande, vous avez deux choix en fonction de ce que vous allez pour. Dépôt droit dit que vous voulez:

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

Mais où le mettre? Pas à l'intérieur du projet, ou de l'éditeur, vous avez raison, ou ils devront avoir accès aux dépôts et cela ne vaut rien. L'extrait ci-dessus est couplé de façon lâche, mais pas réutilisable lui-même. Vous venez atteint les limites du modèle du référentiel.

La prochaine étape est une couche d'adaptateur pour votre application, avec une source commune des dépôts ( StaticServiceWrapper) et soit une sorte d'objet EditorAdapter (ou un agrégat ou tout ce que vous voulez les appeler) ou maintenant , vous pouvez mélanger dans les méthodes d'extension qui peut parler à tout et tous les référentiels nécessaires couramment. Je ne l' ai pas fait exactement de cette façon dans un système de production, mais pour vous montrer un exemple concis:

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

En fait, une fois que votre GetAll, GetById, Ajouter, Mise à jour, suppression du référentiel d'objets est fait, vous devez laisser les seules associations et passer la hiérarchie objet / couche aux parties amusantes comme adaptateurs et Caches et Business Logic ( « Oh , mon! » ).

Créé 14/05/2009 à 03:40
source utilisateur

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