Pattern Repository: como preguiçoso de carga? Ou, devo dividir este agregado?

votos
66

Eu tenho um modelo de domínio que tem o conceito de um editor e um projeto.

Um editor possui uma série de projetos, e um projeto não só tem um proprietário Editor, mas também um número de membros do editor. Portanto, um editor também tem uma série de projetos unidas.

Estou tomando uma abordagem DDD para modelar isto e usando o padrão Repository para persistência. No entanto, eu não grok o padrão bem o suficiente ainda para determinar como eu deveria fazer isso.

Eu estou trabalhando com a suposição de que o Editor e Projeto são potencialmente no mesmo agregado, com a estar Editor de raiz. Posso, portanto, obter um editor e, em seguida, enumerar seus projetos, e pode de lá enumerar Editores membros os projectos.

No entanto, se eu só estou autorizado a recuperar Editores do meu repositório, não que isso significa que eu tenho que carregar todos os projetos do repositório quando eu chegar o Editor de que as possui? E se eu quiser carga preguiçoso Editores membros, o projeto precisa de uma referência para o repositório também?

Alternativamente, se eu dividir o agregado e ter um repositório Editor e um repositório do projeto, como devo lidar com uma transação em toda a dois, como quando um novo projeto é adicionado a um editor? Por exemplo:

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

Estou interpretando mal a intenção do repositório padrão?

Publicado 19/01/2009 em 15:10
usuário
Em outras línguas...                            


4 respostas

votos
3

Ela depende das necessidades do seu aplicativo. Se é um grande problema para carregar todos os projetos para um determinado Editor, em seguida, tentar um padrão de carregamento lento como um Proxy Virtual .

Em relação carregar preguiçosamente Editores membro de um projeto, se você usar Virtual Proxy, não vejo um problema injetando o proxy com o EditorRepository desde que eu não considero o proxy para ser parte do domínio.

Se você dividir o agregado, você pode investigar a Unidade de Trabalho padrão como uma solução para atomicidade. Este problema, no entanto, não é exclusivo para DDD e eu tenho certeza que existem outras soluções para o comportamento transacional.

Respondeu 23/01/2009 em 01:45
fonte usuário

votos
4

Que tal dividir responsabilidades em um EditorOwner e um EditorMember?

Sem saber o seu domínio, eu imagino que eles têm responsabilidades diferentes - por exemplo, o EditorOwner pode ser bastante rica (e poderia ser a raiz agregada), mas o projeto só pode precisar de saber uma quantidade limitada sobre seus membros, de modo o objecto EditorMember pode ser bastante leve.

Esses objetos de domínio também podem dizer respeito aos usuários, mas que seria em outro contexto.

Isso ajuda as coisas, ou apenas torná-lo mais complicado?

Respondeu 23/01/2009 em 03:55
fonte usuário

votos
0

Aqui você tem 2 relacionamentos diferentes, um para a posse e um para a adesão.

A relação de propriedade é um simples um para muitos (um proprietário para cada projeto). A relação adesão é muitos para muitos (muitos editores de projeto, muitos projetos por editor).

Você poderia fornecer uma propriedade Proprietário na classe de projeto, e fornecer um método no ProjectRepository para obter todos os projetos de propriedade de um editor específico.

Para a muitos, fornecem uma propriedade de membros da classe Project, e um método no ProjectRepository para obter todos os projetos que contêm o Editor especificado como membro.

Parece também que a Editores e Projetos são entidades, eu provavelmente iria dividir o agregado, mas talvez esses termos têm um significado específico em seu contexto que tornam subentidades de um agregado.

Respondeu 11/02/2009 em 12:01
fonte usuário

votos
30

Estou interpretando mal a intenção do repositório padrão?

Eu vou dizer "sim", mas sei que eu e todas as pessoas com quem trabalhei pediu a mesma coisa pela mesma razão ... "Você não está pensando 4 dimensionalmente, Marty".

Vamos simplificar um pouco e ficar com construtores em vez de criar métodos de primeira:

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

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

Por baixo, o seu repositório do projeto é sempre armazenar um proprietário válido ( p.EditorId) nos dados do projeto, como ele é criado, e no entanto você re-preencher projetos de um editor, ele vai estar lá. Este é por isso que é uma boa prática para colocar todas as propriedades necessárias para construtores. Se você não quer passar todo o objeto, apenas o e.Idfará.

E se eu quiser carga preguiçoso Editores membros, o projeto precisa de uma referência para o repositório também?

Agora, quanto à forma de re-preencher projetos de um editor on demand, você tem um par de escolhas dependendo do que você está indo para. Repositório reta diz que deseja:

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

Mas onde colocá-lo? Não dentro do projeto, ou um editor, você está certa, ou eles terão de obter acesso a repositórios e isso não é bom. O trecho acima é baixo acoplamento, mas não é reutilizável por conta própria. Você acabou atingido os limites de Pattern Repository.

Em seguida é uma camada de adaptador para a sua aplicação, com um código compartilhado de repositórios ( StaticServiceWrapper) e quer algum tipo de EditorAdapter objeto (ou agregado ou o que quer que você chamá-los) ou agora você pode misturar em métodos de extensão que pode falar com qualquer e todos os repositórios necessários fluentemente. Eu não fiz exatamente desta forma, em um sistema de produção, mas para mostrar-lhe um exemplo conciso:

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

Basicamente, uma vez que seu GetAll, GetById, adicionar, atualizar, remover repositório de objetos é feito, você tem que deixar as associações sozinho e seguir em frente até a hierarquia objeto / camada para as partes divertidas, como adaptadores e caches e lógica de negócios ( "Oh , meu!" ).

Respondeu 14/05/2009 em 03:40
fonte usuário

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