Mas é exatamente por isso que eu não entendi, isso é a vantagem básica se se usar DI em qualquer coisa, não é específica desse caso.
De qualquer forma, eu acho complicado injetar repositórios em entidades, serviços são mais simples de se utilizar e manter.[/quote]
Se o servico fizer sentido no domínio eu concordo contigo. Mas nos casos onde a entidade é quem deve fornecer as informações e precisa do repositório para isso, não vejo muito sentindo em implementar esta operação em outro lugar e tirar essa responsabilidade da entidade.
Quem lhe dá independência de banco de dados é o DAO, não o Repository.
Pra mim a função do repositório é mesmo uma função de domínio.
Aproveitando meu exemplo anterior, veja o código abaixo:
[code]
// um metodo de negócio para o repositorio
List<Aluno> alunosEmDebito = repositorioAluno.obtemAlunosEmDebito();
…
//um metodo de negócio para o Aluno
aluno.agendaAvaliacao(avaliacaoSubstitutiva).paraData(dataDaAvaliacao);[/code]
A linguagem é clara e distingue bem os deveres do repositorio e da entidade. Utilizando métodos estáticos na entidade para agir como repositório, essa divisao de responsabilidade não ficaria tão clara (Aluno.obtemAlunosEmDebito()), além de dificultar os testes unitários.
Isso é verdade. Como já disse, se o sistema esta sendo desenvolvido em RoR, seria besteira não utilizar AR (ignorar uma funcionalidade que esta alí de graça por “particularidades de design”, não parece ser uma escolha muito sensata). Já fazer isso em Java, é tão insensato o quanto.
[quote=Lezinho]Um repositório, diferente de uma factory, tem sentido real. É fatídico que as informações do negócio devem ser armazendas em algum repositório de dados, isso faz parte do core business, assim como a recuperação destes objetos. Este lugar de armazenamento é o repositório… o negócio tem conhecimento disso.
A Factory é um simples artifício de criação, irrelevante para o negócio.
[/quote]
Eu sei que o topico nao é sobre factories mas gostaria de esclarecer alguns pontos.
Factories encapsulam a criacao complexa de alguns objetos de dominio. Você pode delegar à factories a reconstituicao de objetos ja persistidos, não é só criacao de novos objetos. E um dominio pode nao precisar armazenar informacoes, assim como nem todo dominio possui agregados complexos que justifiquem factories. Um “sentido real” para cada conceito é relativo, depende de cada caso.
Outra coisa, não faz parte do core business que as informacoes devam ser armazenadas no repositorio de dados. Faz parte sim de algum core business que uma mesma conta bancaria criada agora deve ser acessível posteriormente. Essa existencia atraves de diferentes ciclos de vida é o que define o conceito de entidade.
Factories e repositorios sao utilizados para suportar ciclos de vida dos objetos de dominio, ambos sao irrelevantes para o negocio.
[quote=cmoscoso]Outra coisa, não faz parte do core business que as informacoes devam ser armazenadas no repositorio de dados. Faz parte sim de algum core business que uma mesma conta bancaria criada agora deve ser acessível posteriormente. Essa existencia atraves de diferentes ciclos de vida é o que define o conceito de entidade.
Factories e repositorios sao utilizados para suportar ciclos de vida dos objetos de dominio, ambos sao irrelevantes para o negocio.[/quote]
É de total relevância para a conta bancária informações sobre o rendimento total de uma determinada poupança em um período. Essa consulta faz parte do negócio e tem valor p/ o cliente, inclusive essa é a linguagem natural que ele usa.
Como ele é buscado na infra, não interessa, um DAO ou outro meio me retorna isso, mas essa funcionalidade de extração da informação é de grande importância. A assinatura deste método de busca de dados, tem que ser ubiquitous e conhecida pelo especialista do domínio e pela equipe de desenvolvimento.
A relevância da factory é mais branda. Um repository pode utilizar uma factory para montar uma informação, mas isso não é lá tão transparente para o negócio, mesmo sendo necessário para o domínio.
Quem dá independência de banco de dados é uma abstração ao acesso a fontes de dados, como um repositório. Não é possível conseguir independência de bancos de dados em um AR porque não existe um AR sem um banco de dados. Não entendi o que o DAO tem haver com isso na história.
Não consigo ver qual o problema de clareza em Aluno.obtemAlunosEmDebito() se comparado ao repositório, ambos passam a mesma idéia. Sobre testes unitários, ARs também não dificultam em nada, você tem algum exemplo aonde um AR torne testes unitários mais complexos?
O repositório vem para servir o domínio como uma coleção de objetos vivos em memória. Quem mascara o acesso é um DAO ou outro meio. Eu costumo ter uma interface DAO como componente de meus repositórios:
public class RepositorioAlunoImpl implements RepositorioAluno{
@In
private DataAcessObject dao;
public void adiciona(Aluno aluno){
//pode realizar alguma rotina comum
//ao objeto 'aluno' antes de persistir seu estado
....
dao.persiste(aluno);
}
}
Esta é ‘uma’ possível implementação.
O repositório atua como mediador entre o domínio(onde ele esta) para a persistence layer onde esta o DAO, quase sempre, DataMapper (conforme indicação do padrão). Sua afirmação anterior de que:
… é mais focada no DAO, na infra, e não no Repository.
A instrução Aluno.obtemAlunosEmDebito não é clara para o domínio. Os alunos em débito habitam onde? Em “Aluno”? Aluno é um tipo e não uma caixa que armazena dados. Essa é a diferença.
Quanto aos testes, “obtemAlunosEmDebito” com AR da forma descrita anteriormente é um dado estático, imutável (em Java). Caso você tiver em mãos ponteiros de métodos, não tem problema, caso contrário criar uma interface repositório se torna uma saída bem mais interessante de se implementar objetos falsos.
Bom, esta é uma visão que tenho (com vista no que tenho olhado por aí), pois nunca implantei em Java AR para dizer mais sobre testes unitários com estes. Inclusive estou curioso para saber qual seria uma saída boa para isso.
Como eu disse antes essa é uma discussõa que está misturando coisas completamente diferentes. Uma coisa é como seu Domain Model vê persistência (seja com Repository ou não) outra coisa é como persistência é implementada (AR ou DM). Pode ser mais natural pensar em um Repositório acessando/sendo implementado por um DataMapper mas nada impede que um Repositório acesse/seja implementado por um Active Record. Para quem trabalha com Java é provavelmente mais difícil porque a linguagem adiciona tanto ruído sintático que não dá para ter Active Records limpos mas em plataformas como Ruby isso não é verdade.
Resumindo:
Não é preciso ter Repository (ou qualquer outro padrão) para ter Domain-Driven Design
Um Repository pode abstrair qualquer implementação/estratégia de persistência, o domain model não está nem aí para isso
Se tem valor pro negocio deverá ser implementado no dominio, mas não é requisito de nenhum negocio que seja feito por meio de repositorios.
A implementacao de repositorios é sempre transparente para o negocio, pelo menos deveria ser. De qualquer forma, eu ja vi factories utilizando repositorios, nao o contrario.
Diferentes porém necessárias e relevantes. Isolamento do domínio e abstração da infraestrutura fazem parte de qualquer modelagem de sistema q queira ser desenhada com DDD.
[quote=pcalcado]
Não é preciso ter Repository (ou qualquer outro padrão) para ter Domain
Driven Design[/quote]
Com certeza, inclusive é isto que eu estava defendendo a pouco em outro tópico. Para ter Domain-Driven você precisa retratar o domínio em espécie e comportamento. O design proposto também preza pelo isolamento deste domínio, abstraindo a infraestrutura. Implementar Active Record em Java não ajuda em nenhum destes requisitos.
Como você, o Maurício e eu tbm concordo, Active Record em Java não é uma estratégia natural(seria muito intrusivo no modelo, o que não é a realidade em Ruby).
Uma coisa que não entendi e realmente gostaria de entender foi a colocação:
Como implementar ‘repositório’ com AR? Como abstrair em um modelo estático o que de fato é o Active Record? A não ser que a linguagem lhe dê subsídios dinâmicos, não vejo como fornecer esta abstração.
O repositório vem para servir o domínio como uma coleção de objetos vivos em memória. Quem mascara o acesso é um DAO ou outro meio. Eu costumo ter uma interface DAO como componente de meus repositórios:
public class RepositorioAlunoImpl implements RepositorioAluno{
@In
private DataAcessObject dao;
public void adiciona(Aluno aluno){
//pode realizar alguma rotina comum
//ao objeto 'aluno' antes de persistir seu estado
....
dao.persiste(aluno);
}
}
Esta é ‘uma’ possível implementação.
O repositório atua como mediador entre o domínio(onde ele esta) para a persistence layer onde esta o DAO, quase sempre, DataMapper (conforme indicação do padrão). Sua afirmação anterior de que:[/quote]
Quem mascara o acesso a uma fonte de dados é o repositório, se você está usando um DAO dentro do repositório, é uma opção de implementação sua, não existe problema nenhum da própria implementação do repositório fazer acesso ao banco de dados/mecanismo de persistência não. No DDD mesmo (o livro) os repositórios de rodam o SQL direto, não usam mais ninguém no meio pra fazer isso não. Não vejo porque misturar DAOs e repositórios, quando ambos fazem a mesma coisa, eles só tem “idéias” diferentes.
Não são relevantes, não nesta discussão. Desde que você abstraia a implementação pouco importa como ela é feita.
[quote=Lezinho]
Como implementar ‘repositório’ com AR? Como abstrair em um modelo estático o que de fato é o Active Record? A não ser que a linguagem lhe dê subsídios dinâmicos, não vejo como fornecer esta abstração.[/quote]
Numa linguagem de tipagem estática meia-bomba como Java você pode fazer o Repository delegar para o AR ou o AR implementar o Repository (no caso é melhor ter também uma interface só com os métodos do objeto de negócio).
[quote=cmoscoso]
Se tem valor pro negocio deverá ser implementado no dominio, mas não é requisito de nenhum negocio que seja feito por meio de repositorios.[/quote]
Mas repositório é domínio … e se ele cuida da recuperação de objetos, não vejo porque não estar nele.
Repositório pode conter lógica, não apenas buscar dados de forma bruta e restaurar da mesma forma para seu solicitante. Por isso, um repositório pode sim (mas não obrigatoriamente), conter factories que auxiliem a montar, por exemplo, um coleção de objetos modificados. Não existe restrição quanto a isso.
Model-Driven Design é uma parte de Model-Driven Development. Basicamente significa que você vai ter o modelo como guia principal do seu projeto e você não precisa usar DDD para usar o modelo como cerne do seu design.
Eu nao disse que repositorios nao podem utilizar factories, eu disse que ainda nao vi sendo utilizado dessa maneira, mas o ponto é que nao importa para o negocio como o repositorio sera implementado.
Ou seja, IMHO repositorios nao devem conter regras de negocio.