DAO's nas classes de negócio

Opa pessoal, tudo bom?

Eu tenho uma dúvida quanto ao reuso dos métodos de “CRUD” no caso, por exemplo, qual seriam as formas mais elegantes de eu nao ter que implementar métodos como Person.get() , ou Person.list() em todos o meus objetos de négocio?

Acho que fica melhor (em Java) deixar esses métodos no repositório / dao.

Olá,

esta discussão está ótima!

[quote=TriTonE]Segundo alguns textos que li sobre DDD, os factories servem tanto para CRIAR objetos complexos quanto para RECONSTITUIR objetos (por exemplo, objetos carregados do repositório).
[/quote]
Eu entendi diferente. As factories apenas criam objetos novos enquanto é responsabilidade do repository carregar objetos existentes.

Não sou fã da idéia de reaproveitar as factories dentro do repositório também. Eu preferiria deixar a responsabilidade da contrução do objeto existente no framework ORM. Li este artigo ontem e parece que tornaria isto possível.
Migrating to Spring 2: Part 3 - injecting dependencies into entities

Quero reforçar esta dúvida. Eu prefiro colocar métodos como get(), list() e find() como sendo estáticos, ou seja, prefiro “Aluno.getAll()” ao invés de “new Aluno().getAll()”. Já que estamos falando em OO fica estranho uma instância de aluno conhecer e listar outros alunos que não são ele. Enfim… como vocês tem lidado com isso?

[quote=Shoes]Segundo, você não precisaria ter um método para este tipo de coisa, aliás se você tiver muitos métodos assim é sinal que seu design é bem ruim. Você resolve isso com outra dupla: Specification/QueryObject.
[/quote]
Não querendo ser folgado… :mrgreen: Mas você possui alguma referência para nos indicar para estudar sobre os padrões Specification e QueryObject? Desde os fundamentos e um exemplo mostrando o caminho das pedras para implementá-los?
Obs: Ainda não pesquisei muito no google mas vou pesquisar com certeza.

Acabei de ler o tópico desde o início (ótimo, por sinal), mas algumas afirmações me dixaram com dúvida,

[quote=pcalcado]… I used to have:

Domain Object --&lt<depends>&gt--&gt Repository &lt--&lt<implements>&gt-- DAO

And changed to:

Domain Object --&lt<depends>&gt--&gt Repository

Repository &lt--&lt<implements>&gt-- RepositoryImpl --&lt<depends>&gt--&gt DatabaseDao--&lt<depends>&gt--&gtSearchEngineDao


[/quote]

Segundo o trecho acima, o padrão Repository pode ocasionar em uma camada a mais no design do sistema, dependendo do caso, tudo bem. Mas o que me deixou em dúvida foi a dependência de RepositoryImpl com DatabaseDao… me parece que os 2 ficam com uma dependência forte, ficando o RepositoryImpl sabendo como os dados são armazenados. Neste caso ele ficaria fora da camada de negócio? De repente este exemplo ficou bem abstraído e eu não entendi direito.

Quanto ao MVC:

[quote=pcalcado]Acho que você entendeu errado o Model no MVC, por isso esta confusão. Model em MVC é: -&gt UserRepository -&gt Implementação concreta do repositório MySQLUserRepository -&gt Banco de dados. Tudo isso.
[/quote]

[quote=pcalcado]Problema com seu exemplo: Action não tem nada a ver com Repository. Action é MVC e MVC é Camada de Apresentação, estamos falando da integração entre negócios e Persistência.
[/quote]

Também sempre considerei MVC como apresentação, conforme a segunda afirmação, mas a primeira parece dizer o contrário… talvez não tenha ficado claro o que o Philip quiz dizer com a primeira afirmação e se puder esclarecer um pouco… :slight_smile:

[quote=Thiago Senna]Olá,

esta discussão está ótima!

[quote=TriTonE]Segundo alguns textos que li sobre DDD, os factories servem tanto para CRIAR objetos complexos quanto para RECONSTITUIR objetos (por exemplo, objetos carregados do repositório).
[/quote]
Eu entendi diferente. As factories apenas criam objetos novos enquanto é responsabilidade do repository carregar objetos existentes.[/quote]

Sim, você vai utilizar o repository para carregar um objeto. Quando salvamos objetos no repositório, é comum termos atributos “transientes” (referências para services, repositories etc). Então você acaba tendo que satisfazer as dependências dos objetos carregados dentro do repositório mesmo, como você disse. No entanto, quando criamos novos objetos, TAMBÉM temos que fornecer as dependências.

No caso, faz mais sentido “estender” um pouquinho a responsabilidade dos factories de modo a criar e “remontar” objetos. Dessa forma, seu repositório terá uma referência ao factory que, por sua vez, será utilizado para preencher as dependências necessárias antes de retornar o objeto.

Fazendo desse jeito, teremos a lógica a montagem de objetos (criação e reconstituição) em um único local, o que, ao meu ver, facilita a manutenção.

[quote=Thiago Senna]Não querendo ser folgado… :mrgreen: Mas você possui alguma referência para nos indicar para estudar sobre os padrões Specification e QueryObject? Desde os fundamentos e um exemplo mostrando o caminho das pedras para implementá-los?
Obs: Ainda não pesquisei muito no google mas vou pesquisar com certeza.
[/quote]

Tem uma referncia ótima aqui.

O Repositório sabe como os objetos são persistidos, em quais lugares, etc. Ele é um objeto na frotneira entre Negócios e Persistência.

[quote=mutano]
Também sempre considerei MVC como apresentação, conforme a segunda afirmação, mas a primeira parece dizer o contrário… talvez não tenha ficado claro o que o Philip quiz dizer com a primeira afirmação e se puder esclarecer um pouco… :slight_smile: [/quote]

Neste diagrama:

O Model é composto por tudo menos o cercado em vermelho.

Fonte: http://fragmental.com.br/wiki/index.php?title=MVC_e_Camadas

Cara, eu preciso estudar muuuuuito

Tudo entendido sobre Repositorios e DAOs…
Mas eu ainda estou com uma duvida em um sistema que estamos iniciando agora (e que essa thread me ajudou bastante) que é o seguinte:
Nesse sistema, tem horas que eu “vou” num Oracle via JPA, outras em WebServices, outras na plataforma alta via MQSeries e outras em um XMLDB. Pois bem, o Repositorio e o DAO funcional perfeitamente nesses casos. Mas que objeto (nome e tipo) eu devo retornar nesses vários caminhos…
Hoje eu tenho um monte de DTOs… nesse caso, qual o conselho de vcs? E no caso do Entity do JPA? Eu não acho legal retornar um objeto todo anotado… o que fazer?!?

[quote=rodrigoallemand]Mas que objeto (nome e tipo) eu devo retornar nesses vários caminhos…
Hoje eu tenho um monte de DTOs… nesse caso, qual o conselho de vcs? E no caso do Entity do JPA? Eu não acho legal retornar um objeto todo anotado… o que fazer?!?[/quote]

Seu problema não tem tanto a ver com Repositórios ou DAOs e sim com objetos de negócio. Você deve retornar Entities e seus Aggregates segundo Domain Driven Design, que não necessariamente são Entities JPA mas que pdoem ser sem problemas. Anotações foram criadas exatamente para abstrair dos objetos infra-estrutura como persistência ou transações.

Não conheço DDD a fundo… mas como essa camada de negocio ficará exposta para outros serviços (via JAR ou via transação remota) como seriam os objetos?!? Digo como seriam, assim, POJOs, destacados dos objetos utilizados no caminho até o repositorio real, etc…

[quote=pcalcado]
Anotações foram criadas exatamente para abstrair dos objetos infra-estrutura como persistência ou transações.[/quote]
Idem acima. Em alguns casos, esses objetos de negocio devem ser expostos para outro sistema. Não ficaria “feio” mandarmos um objeto com configurações de mapeamento anotadas?!? Em contra partida, duplicar objetos somente para tirar as anotações seria um tiro no pé, já que atualizações deverão ser em dois lugares agora…

O problema é: eu preciso expor objetos (POJOs). Vcs acham que ficaria “feio” expor objetos anotados?

Sem entrar no mérito das anotações, quando o assunto é integração, ficaria “feio” expor os próprios Pojos. Se assim o fizer estará acoplando suas aplicações cliente ao seu modelo, e isso é ruim. Imagine, se elas forem forçadas a recompilar suas aplicações toda hora que vc adiciona/atualiza/exclui um atributo em qualquer Pojo do seu modelo, .

XSDs podem ser opções mais elegantes quando o problema é definir “padrões” de dados que devem trafegar entre aplicações.

[quote=pcalcado] Dificilmente existe um Entity (falando no jargão DDD) que seja criado manualmente, geralmente ele é criado por um Factory Method em um Service (outra vez DDD) que já cuida destas coisas.
[/quote]

Não sei se estou misturando as bolas mas,

Este factory method também faz e registro do objeto como limpo em uma unidade de trabalho?

[quote=pcalcado][quote=Thiago Senna]Não querendo ser folgado… :mrgreen: Mas você possui alguma referência para nos indicar para estudar sobre os padrões Specification e QueryObject? Desde os fundamentos e um exemplo mostrando o caminho das pedras para implementá-los?
Obs: Ainda não pesquisei muito no google mas vou pesquisar com certeza.
[/quote]

Tem uma referncia ótima aqui.[/quote]

Será que resumo da infoq chega a falar sobre isso? Vou dar uma olhada…

[quote=Taz]
Sem entrar no mérito das anotações, quando o assunto é integração, ficaria “feio” expor os próprios Pojos. Se assim o fizer estará acoplando suas aplicações cliente ao seu modelo, e isso é ruim. Imagine, se elas forem forçadas a recompilar suas aplicações toda hora que vc adiciona/atualiza/exclui um atributo em qualquer Pojo do seu modelo.[/quote]

Desculpa se estou sendo muito burro!

Você só precisa recompilar uma classe quando a interface de uma classe que ela depende muda! (Ou to viajando?)

Eu penso que se as interfaces dos seus pojos são estaveis vc pode acoplar qualquer coisa a eles. A implementação pode mudar a qualquer hora sem que vc tenha que recompilar seu cliente!

Falo de interface como sendo os métodos que a classe fornece!

"Teve uma época que li programe somente para “interfaces”! Sai criando interface para tudo! sem nem ter necessidade! hauhahauhauha o mula!

Tópico Hellraiser…heheheheh…

Da pra fazer isso nesse caso:

@MappedSuperclass
public abstract class Pessoa{
      //Varias annotations de mapeamento...
}

Dai tu expõe apenas a:

@Entity
public class PessoaEntity extends Pessoa {
}

Melhoraria um pouco o problema. Não o excluiria por completo. Outra solução para não expor configuração seria voltar ao XML.

Aproveito que o tópico foi ressucitado para recomendar a leitura do mesmo. :smiley: É um dos tópicos clássicos do GUJ.

Boa madrugada gente!!! :slight_smile:

Estou estudando sobre DDD e este post best seller ajudou totalmente.

No final das contas me restou uma dúvida:

Nos no meu “UserRepository” eu tenho algo mais relacionado ao negócio, suponhamos que eu precise de encontrar “Todos usuários com salário > 5.000, que tenham Casa própria quitada, que não tenha filhos, seja solteiro etc etc”(considere que seja uma consulta bem complexa) e lá na interface repository eu terei este método "findUsersBemDeVida();

Até ai ok, pois representa algo bem espefíco, mas agora se eu estiver usando este modelo:

UsuarioRepository > UsuarioDecorator(implements UsuarioRepository) > UsuarioDao

Onde ficará meu SQL(HQL seja o que for) dessa consulta?

Considerando que nesse UsuarioDecorator eu já tenha um UsuarioDao para outras consultas gerais, o que seria o correto e/ou melhor pra ser feito?

1- Colocaria dentro do UsuarioDecorator uma instância de uma EntityManager e faria essa consulta diretamente ali sem ir ao UsuarioDao;

2- Delegaria essa consulta para o UsuarioDao(afinal já tenho uma instância dele no UsuarioDecorator) e lá no Dao faria a consulta.

3- Faria todo o SQL dentro do método no UsuarioDecorator, e passaria essa String SQL para um método genérico no UsuarioDao que simplesmente executa a consulta, evitando assim ter que possuir uma instância de EntityManager.

Bem fiquei confusa quanto a isso, a opção 1 me parece estranha ter um EntityManager e um UsuarioDao no Decorator. A opção 2 eu acho sem sentido, se é uma consulta específica do domínio não teria porque ir parar no Dao. A opção 3 eu particularmente acho feio ficar mandando String SQL, tirando isso achei a melhor opção das 3.

Bem posso estar bem errada nos meus pensamentos, mas se alguém puder me ajudar a compreender essa dúvida que ainda me restou.
Alguém pode vir e dizer simplesmente pra esquecer o UsuarioDao e usar apenas o UsuarioDecorator que implementa a interface UsuarioRepository e lá fazer tudo, mas considerando essa minha dúvida, como ficaria de fato essa questão nesse modelo ?

UsuarioRepository > UsuarioRepositoryImpl(meu caso UsuarioDecorator) > Dao > UsuarioDaoImpl

Agradecida a todos pela atenção.

Não entendi, por que você está usando essa hierarquia toda? Que tal uma interface RepositorioUsuarios que é implementada por um UsuárioDAO, uma coisa simples que funciona?

Na implementação do Repositório, o DAO na minha proposta acima.

[quote=pcalcado][quote=carol_programadora]
Nos no meu “UserRepository” eu tenho algo mais relacionado ao negócio, suponhamos que eu precise de encontrar “Todos usuários com salário > 5.000, que tenham Casa própria quitada, que não tenha filhos, seja solteiro etc etc”(considere que seja uma consulta bem complexa) e lá na interface repository eu terei este método "findUsersBemDeVida();

Até ai ok, pois representa algo bem espefíco, mas agora se eu estiver usando este modelo:

UsuarioRepository > UsuarioDecorator(implements UsuarioRepository) > UsuarioDao
[/quote]

Não entendi, por que você está usando essa hierarquia toda? Que tal uma interface RepositorioUsuarios que é implementada por um UsuárioDAO, uma coisa simples que funciona?

Na implementação do Repositório, o DAO na minha proposta acima.
[/quote]

Corrija se eu estiver errado, mas no projeto exemplo do site oficial (dddsample) , existe um exemplo dessa situaçao, onde a interface do repositorio fica na camada de domínio, e a implementação, no caso em Hibernate, fica na camada de infra-estrutura/persistencia.