Dúvida - Comunicação entre camadas+Domain Model

45 respostas
E

Aê galera, tranquilo?! :smiley:

Estou tendo dificuldades com relação a forma correta de haver comunicação entre as camadas em uma aplicação.

Por exemplo: O usuário submete um formulário para cadastro no meu sistema. Observando que eu estarei utilizando JSF, qual seria o percurso correto que o Objeto com os dados do usuário deveria fazer até ser persistido no banco de dados?

Eu pensei em algo como: Página JSF -> Managed Bean -> Repositório; mas tenho dúvidas se deveria haver “alguém” intermediando a comunicação entre o managed bean e o repositório? como um controller por exemplo, sei lá…

Alguma dica com relação a isso?

Outra dúvida que eu tenho é: Se por ventura um médoto de uma entidade precisa interagir de alguma forma com o banco de dados, a entidade deve possuir uma referência direta ao repositório, ou deve haver um “alguém” para coordenar essa operação?

Por exemplo: A entidade executa a operação, envia o resultado ao controller, e este por sua vez aciona o repositório para que o resultado seja armazenado no banco.

Desculpem pelo tamanho do tópico, mas acho que assim as minhas dúvidas ficam mais fáceis de se entender.

Obrigado pela atenção, abraços.

45 Respostas

Rubem_Azenha

Não é sempre que Managed Bean consegue ficar completamente livre de código relativo a camada view. Infelizmente não é sempre que da para usar ele em outras camadas.
Mas eu acho que dificilmente um managed bean se encaixaria na domain layer. Talvez na application layer em alguns casos.

Eu acho que na maioria dos casos não é uma boa o managed bean acessar o repository, prefiro deixar nas entities e em raríssimos casos nos services.

fantomas

E ai Erick,

Estas suas perguntas/dúvidas geralmente geram bastante polemica.

Dá uma olhada nestes links aqui:

http://guj.com.br/posts/list/70275.java
http://debasishg.blogspot.com/2007/12/domain-modeling-what-exactly-is-rich.html
http://debasishg.blogspot.com/2007/02/domain-driven-design-inject.html

Nos casos estremamente simples acho que não teria problemas, eu prefiro não fazer isso eu colocaria um serviço;

Outra dúvida que eu tenho é: Se por ventura um médoto de uma entidade precisa interagir de alguma forma com o banco de dados, a entidade deve possuir uma referência direta ao repositório, ou deve haver um “alguém” para coordenar essa operação?

Por exemplo: A entidade executa a operação, envia o resultado ao controller, e este por sua vez aciona o repositório para que o resultado seja armazenado no banco.

Este ponto é bastante polemico; Acredito que muitos irão dizer/dizem que a entidade deve ter uma referência direta para o repositório mas outros dizem que preferem não envolver questões relacionadas a mecanismos de persistencia nas entidades. Por conta disto, prefiro indicar um livro sobre este e varios outros assuntos relacionados para vc ter uma referencia maior sobre o tema:
http://www.lcm.com.br/index.php?Escolha=20&Livro=L00521

flws

E

Nos casos estremamente simples acho que não teria problemas, eu prefiro não fazer isso eu colocaria um serviço;

Tava pensando a respeito… seria uma boa solução eu adicionar uma fachada pra isolar o meu domínio da camada de aplicação?

Ficaria tipo assim: Página JSF -> Managed Bean -> Fachada -> Repositório;

De que forma as entities poderiam manter referências aos repositórios? No construtor da classe seria instanciado o atributo correpondente ao repositório?

fantomas

Este é o link que fala sobre isto:
http://debasishg.blogspot.com/2007/02/domain-driven-design-inject.html

O problema que envolve esta questão é a seguinte: Geralmente a entidade é instanciada por uma ORM (JPA/Hibernate) e vc iria precisar de informar para o ORM qual é o repositório a ser utilizado. No link acima aponta uma maneira de fazer isso através do SPRING.

Outra maneira seria após a leitura das entidades vc informar o repositório através de um método set (setGrupoRepository(GrupoRepository repository) ) esta forma é indicada no livro que mencionei no post anterior, quem utiliza esta maneira defente um NÃO envolvimento maior das entidade com mecanismo de acesso a dados.

flws

fantomas

Eu acho que sim.

flws

Eduardo_Amuri

A idéia de injetar (Spring) é extremamente mais limpa e vai tornar seu código mais claro.

A idéia de fachada não se aplica no seu caso… o padrão “fachada” foi desenvolvido para suprir deficiências no modelo de objetos remotos proposto pela Sun. Você pode encontrar uma explicação mais detalhada nos blog por ai, mas, resumindo, servia para evitar a grande quantidade de lookup`s remotos nos EJB’s. Ao invés de buscar 3 referencias remotas, busca-se apenas uma, e esta serve como fachada para o serviço prestado pelas outras duas.

Abraços,
Eduardo Amuri

pcalcado

Eduardo Amuri:

A idéia de fachada não se aplica no seu caso… o padrão “fachada” foi desenvolvido para suprir deficiências no modelo de objetos remotos proposto pela Sun.

Hmm… não. Façade é um padrão GoF, catalogado bem antes dos padrões da Sun (e até de J2EE existir).

pcalcado

Erick Jeronimo:

Tava pensando a respeito… seria uma boa solução eu adicionar uma fachada pra isolar o meu domínio da camada de aplicação?

Ficaria tipo assim: Página JSF -> Managed Bean -> Fachada -> Repositório;

De que forma as entities poderiam manter referências aos repositórios? No construtor da classe seria instanciado o atributo correpondente ao repositório?

No fluxo acima eu não consigo ver seu domínio. O que você tem ali é um Transaction Script, não um Domain Model.

E eu não entendi porque você está usando Repositório. Será que você não está apenas mudando o nome do DAO?

Eduardo_Amuri

Hum, entendi. Mas acho que o uso mais evidente, é esse… não? Não acho que se aplicaria no caso do amigo ai de cima.

Eu optaria por algo como:

Página JSF -> Managed Bean -> Serviço -> Repositório;

Existe algum problema nessa abordagem?

E


Hum, entendi. Mas acho que o uso mais evidente, é esse… não? Não acho que se aplicaria no caso do amigo ai de cima.

Na verdade quando eu falei em Fachada eu estava me referindo ao padrão da GoF. Se quiser dar uma olhada tem uma breve descrição do padrão aqui.

No fluxo acima eu não consigo ver seu domínio. O que você tem ali é um Transaction Script, não um Domain Model.

E eu não entendi porque você está usando Repositório. Será que você não está apenas mudando o nome do DAO?

De fato não fui feliz na nomenclatura, aonde lerem repositório podem interpretar como DAO :oops:

pcalcado, na verdade o que seria um “Transaction Script”?

Quando eu fiz a “ilustração” do fluxo de requisições eu quis mostrar situações nas quais a Fachada faz chamadas diretas ao DAO (isso é recomendável?). Eu tenho dúvidas com relação a “quem deve requisitar a quem” no modelo arquitetural que eu ilustrei.

O meu modelo de domínio ficaria entre a fachada e o DAO. Só que a questão é que eu não sei se as classes de entidade devem requisitar “algo” diretamente ao DAO.

Exemplo: Página JSF -> Aplicação (Managed Bean, Fachada…) -> Domínio(Classes de Entidade…) -> Infra (DAO…)

Também tenho dúvida se existe a necessidade de ter alguma classe para se comunicar com o DAO (ao invés da fachada manter uma referência direta ao mesmo).

Eu venho de um modelo onde as regras de negócio ficavam em classes controladoras e as classes de entidade eram apenas um conjuto de atributos+gets/sets. Estou tentando abandonar este modelo (através de leitura e de experiência “própria” percebi que ele não é o mais adequado), porém estou tento certa dificuldade em perceber qual seria o fluxo correto que as requisições devem percorrer.

Orientações são muito bem vindas, obrigado pelas dicas galera! :smiley:

pcalcado

Ok, como DAO e Repositório são coisas diferentes recomendo que mantenhamos o que você está usando como DAO para evitar confusão.

http://www.google.com/search?q=transaction+script

Primeiro hit.

Se sua Fachada faz requisições ao DAO você não tem um Domain Model. Leia o link acima para entender melhor.

Eduardo_Amuri

Erick,

http://dddsample.sourceforge.net/

Talvez lhe interesse =)

E

Interessante cara, eu não sabia da existência de transactions scripts.

Mas assim, é “ruim” ou “errado” fazer uso de transactions scripts?

Em uma abordagem “não transaction scrpit”, de que forma eu poderia realizar os cadastros básicos do sistema sem que a fachada se comunicasse diretamente com o DAO? A entidade de domínio teria o método “cadastrar” que comunicaria com o DAO?

Eduardo_Amuri

Não é errado. Dependendo do seu escopo e do seu propósito, é uma abordagem vantajosa. O site do Fowler explica com maiores detalhes, caso você não tenha acesso ao PEA.

diguix

Não é questão de ser certo ou errado.
Tanto Domain Model quanto Transaction Script são padrões para lógica de domínio, o que não quer dizer você não possa utilizar os dois no mesmo projeto, porém não é aconselhavél pois seu design vai ficar muito ruim.

Procure sobre repositórios, vai te clarear bastante sobre a idéia de como acessar a camada de persistência.
veja: http://gc.blog.br/2009/01/17/sindrome-de-dao/ o Guilherme escreveu recentemente.

Na abordagem do fowler sobre repositórios, acredito não ser a 100% correta sobre trabalhar com DDD, mas já te dar base sobre o assunto.

Abraços

sergiotaborda

Erick Jeronimo:
Aê galera, tranquilo?! :smiley:

Estou tendo dificuldades com relação a forma correta de haver comunicação entre as camadas em uma aplicação.

Por exemplo: O usuário submete um formulário para cadastro no meu sistema. Observando que eu estarei utilizando JSF, qual seria o percurso correto que o Objeto com os dados do usuário deveria fazer até ser persistido no banco de dados?

Eu pensei em algo como: Página JSF -> Managed Bean -> Repositório; mas tenho dúvidas se deveria haver “alguém” intermediando a comunicação entre o managed bean e o repositório? como um controller por exemplo, sei lá…

Alguma dica com relação a isso?

O managedBean do JSF é o controler. Só que ele é o controller da camada de apresentação ( padrão MVC).
Se a operação é uma simples leitura de dados ele pode invocar o repositorio directamente. Se é uma operação que vai mudar o estado do sistema , tal como insert, update , delete ou algum processamento (que resulta em um ou mais insert, update ou delete)
então é bom que o o ManagedBean invoke o controlador de negocio/dominio. O controlador de dominio é um Serviço.
O ManagedBean deve então apenas consumir o serviço e deixar que o serviço faça o seu papel.

Em todos os casos o papel do ManagedBean é traduzir os dados do formato JSF para o formato do dominio e vice-versa. (ou seja, pegar os dados dos escopos certos , invocar o dominio e depois colocar os resultados nos escopos certos)

Quem coordena a operação é o Repositorio. a entidade deve ter uma referencia ao repositorio apropriado, ou localizar um através do padrão Service Locator. No reino da ADI é mais simples que a entidade seja injetada com os repositorios que precisa.
Agora, cuidado com o tipo de invocação que faz ao repositorio. Ela tem que ser read-only sem alterar o estado do sistema.
( básicamente apenas para encontrar outros objetos através de alguma referencia/chave )

entidades não envia coisa alguma a ninguem. É o controler que pede à entidade algo. A entidades não tem referencia ao controlador que a está invocando. Violar isto é violar o principio de inversão de controle, e violar este principio é fazer gambe.

sergiotaborda

A abordagem do Fowler não apenas é a correta como é aquela que é verdadeiramente OO.
O pessoal do DDD aproveitou essa ideia. O problema é que o pessoal do DDD confunde repositorio com DAO, enquanto o Fowler não.
( O DAO é um serviço , o repositorio não é um serviço)

Na real, DAO é coisa do passado. Só se deve usar em sistemas legados que são orientados a dados (que é diferente de sistemas orientados a dominio). Mais sobre isso em :







E

Em primeiro lugar, queria agradecer a ajuda de todos, muitas dúvidas minhas estão sendo esclarecidas. :smiley:

O managedBean do JSF é o controler. Só que ele é o controller da camada de apresentação ( padrão MVC).
Se a operação é uma simples leitura de dados ele pode invocar o repositorio directamente. Se é uma operação que vai mudar o estado do sistema , tal como insert, update , delete ou algum processamento (que resulta em um ou mais insert, update ou delete)
então é bom que o o ManagedBean invoke o controlador de negocio/dominio. O controlador de dominio é um Serviço.
O ManagedBean deve então apenas consumir o serviço e deixar que o serviço faça o seu papel.

Blz Sérgio, entendi melhor a questão de quem deve chamar a quem pra solicitar uma operação. Só tive dúvida com relação à possibilidade de haver um serviço pra realizar inserts, updates e deletes, e o ManagedBean apenas solicitar ao serviço a operação desejada.

Qual o objetivo de separar essas operações em um serviço? sendo que para consultas, o ManagedBean pode solicitar diretamente ao repositório? As operações de insert, update e delete não podem ficar diretamente no managed bean? já que este possuiria uma referência ao repositório mesmo…

Atualmente eu trabalho com tudo dentro do próprio managed bean. Queria entender porque essa abordagem seria incorreta, quais as vantagens (caso haja alguma…), desvantagens, etc…

Obrigado pela ajuda galera, abraços.

sergiotaborda

Normalmente o sistema não fará um save ou delete “puro”. Ou seja, ele vai fazer outras operações. Por exemplo, ele pode enviar emails , informar listeners de eventos, fazer operações de save/delete em cascada, validações , verificação de autorização, log , etc…

No inicio pode parece apenas um save simples no banco, mas à medida que o sistema cresce novas coisas são adicionadas. Se vc não isolar em um serviço o seu ManagedBean vai aumentar em responsabilidade. É esse o problema. Ele não tem , nem deve ter essas responsabilidade. Ele é um item da apresentação. Não deve conter lógicas de negocio. Colocando em um serivo a coisas fica muito mais simples. Um serviço é definido como uma interface e uma ou mais implementações. O que significa que no futuro se vc mudar o serviço o seu JSF não vai nem saber. Esta flexibilidade mostra que as responsabilidades estão bem separadas e isso singifica que é um melhor modelo que meter tudo na mesma classe.

Rubem_Azenha

De onde você tirou “sistemas orientados a dados”?

Marcio_Duran

The JavaServer Faces Managed Bean Facility
A first class Inversion of Control (IoC) Facility for POJOs?

:arrow: Veja na pratica algo relacionado , as colocações do Sergio estão corretas sobre a responsabilidade ao Managed Bean

:arrow: http://www.oracle.com/technology/tech/java/newsletter/articles/jsf_pojo/index.html

sergiotaborda

Rubem Azenha:
sergiotaborda:

De onde você tirou “sistemas orientados a dados”?

é uma expressão para ser comparada com sistemas orientados a dominio. Sendo que o texto é sobre Dados vs Dominio
inevitávelmente tenho que falar em “sistemas orientados a dominio” e “sistemas orientados a dados”.
(sendo que nos texto se define o que é “dados” e o que é “dominio”)

Rubem_Azenha

Ta, mas o que eu quero saber é:você inventou essa expressão ou você tirou de algum outro lugar?

M

sergiotaborda:
Erick Jeronimo:

Qual o objetivo de separar essas operações em um serviço? sendo que para consultas, o ManagedBean pode solicitar diretamente ao repositório? As operações de insert, update e delete não podem ficar diretamente no managed bean? já que este possuiria uma referência ao repositório mesmo…

Normalmente o sistema não fará um save ou delete “puro”. Ou seja, ele vai fazer outras operações. Por exemplo, ele pode enviar emails , informar listeners de eventos, fazer operações de save/delete em cascada, validações , verificação de autorização, log , etc…

No inicio pode parece apenas um save simples no banco, mas à medida que o sistema cresce novas coisas são adicionadas. Se vc não isolar em um serviço o seu ManagedBean vai aumentar em responsabilidade. É esse o problema. Ele não tem , nem deve ter essas responsabilidade. Ele é um item da apresentação. Não deve conter lógicas de negocio. Colocando em um serivo a coisas fica muito mais simples. Um serviço é definido como uma interface e uma ou mais implementações. O que significa que no futuro se vc mudar o serviço o seu JSF não vai nem saber. Esta flexibilidade mostra que as responsabilidades estão bem separadas e isso singifica que é um melhor modelo que meter tudo na mesma classe.

Sérgio,
A arquitetura neste caso ficaria: view -> controller -> services -> persistência
isto mesmo?

Marcio_Duran

Rubem Azenha:

Ta, mas o que eu quero saber é:você inventou essa expressão ou você tirou de algum outro lugar?

:arrow: Desenvolvimento Orientado a Dados é o mesmo que domínio entretanto esse visa um aspecto de persistência(por invocação) que à domínio(foco ao objeto de negócio) ao domain logic as features são persistidas instantaneamente.

tnaires

E o que diabos a gente pode inferir dessa sua resposta? Ele inventou ou não o termo?

peczenyj

Ah, o arquiteto de informação :slight_smile:

sergiotaborda

Mauricio de Mello:
sergiotaborda:

No inicio pode parece apenas um save simples no banco, mas à medida que o sistema cresce novas coisas são adicionadas. Se vc não isolar em um serviço o seu ManagedBean vai aumentar em responsabilidade. É esse o problema. Ele não tem , nem deve ter essas responsabilidade. Ele é um item da apresentação. Não deve conter lógicas de negocio. Colocando em um serivo a coisas fica muito mais simples. Um serviço é definido como uma interface e uma ou mais implementações. O que significa que no futuro se vc mudar o serviço o seu JSF não vai nem saber. Esta flexibilidade mostra que as responsabilidades estão bem separadas e isso singifica que é um melhor modelo que meter tudo na mesma classe.

Sérgio,
A arquitetura neste caso ficaria: view -> controller -> services -> persistência
isto mesmo?

Mais ou menos.

view -> controller -> service (singular) -> persistência

O controller só consome um unico serviço. Se a tarefa necessita da invocação de muitos serviços, cria-se um serviço que chama esses outros na sequencia certa. ( Isso é o padrão Service Façade)
O controller não sabe o que vai acontecer ao chamar o serviço. Portanto ele só pode chamar um único serviço.
Se chamar mais do que um, isso automaticamente implica em que o controller sabe demais pois ele conhece a sequencia lógica das chamadas.

sergiotaborda

Rubem Azenha:
sergiotaborda:

é uma expressão para ser comparada com sistemas orientados a dominio. Sendo que o texto é sobre Dados vs Dominio
inevitávelmente tenho que falar em “sistemas orientados a dominio” e “sistemas orientados a dados”.
(sendo que nos texto se define o que é “dados” e o que é “dominio”)

Ta, mas o que eu quero saber é:você inventou essa expressão ou você tirou de algum outro lugar?

E responder a essa pergunta é importante porque … ?
O importante é entender a mensagem do texto. A mensagem é basicamente que: Dominio não são apenas dados. Sistemas que encaram “cliente” , “produto” apenas como dados são antiquados e votados a fracassar. sistemas legados dos anos 80 e alguns dos 90 e alguns de agora, encaram as coisas assim. É por isso que o Banco de Dados é rei e senhor de tudo e as integrações são complexas porque sempre são no nivel dos dados.
Sistemas orientados a dominio são mais flexiveis porque o banco é apenas um repositorio e a integração acontece ao nivel dos serviços.

Rubem_Azenha

Por que eu estou curioso para saber se você inventou uma abobrinha sem sentido só para menosprezar quem tem uma opinião diferente ou se você se refere a um conceito bem embasado.

A mensagem do texto é: quem usa DAO não sabe fazer software aplicando DDD, o que é na verdade um tremenda bobagem.

E não é por que eu uso DAO que eu trato as entidades como apenas dados ou faço integração via banco de dados.

Já chegamos a conclusão uma vez aqui neste forum a muito tempo atrás que é perfeitamente possível usar DAO interfaceando um repositório e que na maioria dos casos não fazia sentido criar uma camada a mais de repositório ou expor o mecanismo de persistência no repositorio.

Marcio_Duran

E o que diabos a gente pode inferir dessa sua resposta? Ele inventou ou não o termo?
Acho que agente não precisa ser tão religioso contra termos “já ouviu falar em VRaptor Sexy URLs”, então termos são para facilitar uma explicação.

Marcio_Duran

Mudei a assinatura[size=18] ; )[/size]

tnaires

Bom… Não facilitou.

Marcio_Duran

Bom… Não facilitou.
Bom ,não me recordo de alguém dizer se VRaptor Sexy URLs era invencionice ou não, apenas colocaram o termo e ninguém se manifestou, a explicação do Sérgio é coerente e didática, e sobre outro assunto vejo até ligação ao que já estou colocando outras observações indiretas à domínio na questão de Domain Specific Languages no fator “negócios” sobre o uso da melhor tecnologia, algo que é um desenvolvimento orientado a domínio.

sergiotaborda

Rubem Azenha:
sergiotaborda:

E responder a essa pergunta é importante porque … ?

Por que eu estou curioso para saber se você inventou uma abobrinha sem sentido só para menosprezar quem tem uma opinião diferente ou se você se refere a um conceito bem embasado.

Eu não estou preocupado em embassar conceitos. Nem em basear conceitos. É por isso que se chamam conceitos. Conceitos ou vc tem, ou vc não tem. Podem-se ensinar e podem-se aprender, mas não se podem justificar.

Por exemplo, justifique que 2 é maior que 1.
Simplesmente é.

Se eu quisesses basear os conceitos - ou sei lá o que vc quiz dizer com essa frase - eu escrevia papers e dava palestras. Sendo que é um blog de exposição de ideias o objetivo é cada um ler e tirar suas conclusões.

é uma pena que vc só tenha entendendo isso porque isso nem está no texto. E eu nunca disse isso.
Vc pode usar DAO à vontade. MAs DAO verdadeiro, não esse hibrido metamorfoseado que o pessoal chama de DAO, mas que na realidade é uma camada para chamar o hibernate.

O texto tem um obejtivo muito simples:

http://sergiotaborda.wordpress.com/2008/10/06/dados-vs-dominio/:

Parece que a diferença entre um sistema orientado ao domínio e um sistema orientado a dados ainda não está bem clara. Isto é um problema importante porque sem a clara diferenciação entre os dois paradigmas não é possível entender e comparar as vantagens e desvantagens de cada um.
(…)
Em um sistema orientado a dados o mais importante é o ciclo de vida dos dados. Criação - Preservação - Procura - Edição/Remoção - Atualização. Normalmente o foco é a Preservação.
(…)
Bom, mas afinal em que a orientação ao domínio é diferente? A primeira coisa é que a orientação ao domínio é, explicitamente, orientada a objetos. O objeto, não os dados, são o principal componente.O objeto, não os dados, são o principal componente. Repare que os dados são 50% de um objeto: o estado. Os outros 50% - o comportamento - eram largamente espalhados pelos sistemas, resultando em código duplicado de difícil manutenção. Era esse o papel das procedures e dos triggers: serem o comportamento dos dados.

Se vc não enxerga diferença entre “objeto” e “dado” não é problema meu.
O objetivo do texto é apenas dizer que ha diferença e basear a afirmação de que ha diferença.
O objetivo do texto não é cunha novas palavras ou conceitos.

Eu sei que vc sofre de Sindrome de DAO e já o alertei para o problema. Vc não enxerga além disso. O que eu posso fazer? Um dos sintomas é exatamente achar que não está infetado. Tlv a mesma opinião dita por outras pessoas valha mais. Usar DAO com DDD é palhaçada sim! Confundir DAO com Repository é palhaçada sim!

Rubem_Azenha

Eu realmente espero que ao falar que DAO é uma camada para chamar o Hibernate você apenas dado um exemplo e não falado que DAO serve só para Hibernate…

A diferença entre um sistema orientado ao domínio e um sistema orientado a dados ainda não está bem clara por que, pelo que você mostrou, esses dois conceitos foram inventados por você mesmo.

Ok, então vamos usar um termos mais conhecidos e com um embasamento mais forte?
Quando você diz sistemas orientados a dados você quer dizer sistemas com uma arquitetura que usa Transaction Scripts ao invez de Domain Model? Ou simplesmente sistemas que usam DAO? Ou simplesmente sistemas que tenham “VOs” burros?

Eu entendo que uma arquitetura complexa de DAOs não é bom, e você é melhor fazer loja.getProdutosVendidosEm(data) do que lojaDAO.findProdutosVendidosEmData(loja, data), mas o uso de DAO não inviabiliza fazer loja.getProdutosVendidosEm(data). Eu, por exemplo, faria o método loja.getProdutosVendidosEm(data) chamar internamente um DAO (ta, pode ser interfaceado por um repository, já discuti isso uma vez com o Shoes e eu concordei com ele quando ele disse que nomenclatura faz uma grande diferença). Ou você exporia um EntityManager (ou uma Hibernate session, uma JDBC connection, uma FileInputStream, um SocketChannel, uma chamada a um WS) na entity Loja?

Agora, poste alguns exemplos de código de repositórios seus, vamos ver se é muito diferente dos DAOs interfaceando repository :slight_smile:

Rubem_Azenha

Aliás, Sérgio, agora que eu vi que você linkou o blog do Guilherme Chapiewski, eu já tinha lido esse post na época que ele postou (é um dos blogs que eu “assino” o feed) e acho que você não deve ter lido até o final do mesmo:

(o grifo é meu)

Marcio_Duran

:arrow: (Não é o que diz Martin Fowler) Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers

Marcio_Duran

:arrow: [color=blue](Nota uma observação melhor ainda)[/color]:A Repository is a domain level artifact and mostly corresponds to an Aggregate Root. One repository can be implemented in terms of multiple DAOs. One DAO roughly corresponds to a single table. Hence you can say that a Repository is at a higher level of abstraction than the DAO.

sergiotaborda

Rubem Azenha:
sergiotaborda:

é uma pena que vc só tenha entendendo isso porque isso nem está no texto. E eu nunca disse isso.
Vc pode usar DAO à vontade. MAs DAO verdadeiro, não esse hibrido metamorfoseado que o pessoal chama de DAO, mas que na realidade é uma camada para chamar o hibernate.

Eu realmente espero que ao falar que DAO é uma camada para chamar o Hibernate você apenas dado um exemplo e não falado que DAO serve só para Hibernate…

O problema é o seguinte: existe um conceito de DAO e existem dois usos desse conceito. Duas formas de implementar/usar. Uma é boa prática, a outra não. A boa prática é aquela relacionada ao desacoplamento do seu programa do acesso aos dados. Essa é a forma antiga, desenhada pelos EE patterns. A forma ruim é aquela em que o DAO é uma desculpa para encapsular o hibernate ou o EntityManager. É esta segunda forma a que referi como hibrido. A pessoa pensa que está seguindo a boa prática, mas na realdiade não está porque um sistema DAO com hibernate não é independente do hibernate ( por exemplo, vc tem usar o padrão session in view) , logo, isso viola a permissa original do padrão DAO que é poder trocar de implementação sem trocar nada mais na aplicação ( por isso que o DAO é definido como uma interface). Ora, quem usar hibernate/JPa não pensa em trocar de implementação. Aliás, isso nem é possivel. JPA e Hibernate são implementações de DomainStore que é um padrão inerentemente orientado a dominio. O modelo do dominio é explicito e impregnado em todos os usos do hibernate/JPA ( seja com anotações ou xml, não importa. )Vc tem que ensinar ao Hibernate/JPA o seu dominio. Com o DAO original vc não tem que ensinar nada, porque não ha dominio , existem apenas dados.

O outro lado da historia é a confusão entre DAO e Repositorio. Os conceitos podem parecer semelhantes à primeira vista, mas não são sequer da mesma familia. DAO é um serviço de infraestrutura ( usa a dobradinha interface+implementação e é independente do dominio) Repositorio é um agente do dominio ( não é definido por interface+implmentação e é dependente do dominio )
São coisas bem diferentes. Relutar em ver a diferença se escondendo na semelhança aparente é um erro. Persistir nesse erro é uma doença: o Sindrome de DAO.

A diferença entre um sistema orientado ao domínio e um sistema orientado a dados ainda não está bem clara por que, pelo que você mostrou, esses dois conceitos foram inventados por você mesmo.
[/quote]

Em um sistema orientado a dados, os dados são mais importantes que o comportamento. Vc modela dados. Vc guarda dados. Vc se preocupa com o ciclo de vida de dados. E principalmente os dados são burros ( desprovidos de inteligência de negocio). As regras de negocio são colocadas em outros lugares e espalhadas pelas diferentes camadas. As responsabilidades são mal definidas e é confuso entender quem faz o quê.

Em um sistema orientado a dominio o dominio é o mais importante e o resto é apenas uma forma de acessar o dominio ou dar suporte à existencia do dominio. Aqui o mais importante são os serviços que atuam sobre os dados e dos dados são encapsulados em objetos com inteligencia ( aka comportamento) . Padrões como strategy e template method são possiveis. Vc ainda guarda dados, mas esses dados são extraidos do dominio (são apenas os estado dos objetos) Vc se preocupa com o ciclo de vida dos serviços e não dos dados. As regras de negocio está em lugar apenas e não ha confusão da responsabilidade de cada camada.

Não tem nada a haver com os padrões. Tem a haver com a postura. Com as diretrizes que regem as suas escolhas.
Vc pode fazer um sistema orientado a dominio com EJB ( como eu tento explicar no texto) ou usando DAO e Transaction Scripts.
Ou vc pode fazer um sistema orientado a dados como repositorios , façades e SOA. É tudo uma questão de ao quê vc dá importância. Se os seus VO são burros não significa que não esteja orientando o seu sistema ao dominio, pode acontecer que simplesmente não ha nenhuma inteligencia a ser acoplada a esses dados. Agora, escolher não acoplar inteligencia, nunca, mesmo quando precisa, isso sim é sinal de o sistema é orientado a dados. O exemplo clássico é ter um método estático na classe A para fazer algo que podia ser um método publico da classe B.

sergiotaborda:

Agora, poste alguns exemplos de código de repositórios seus, vamos ver se é muito diferente dos DAOs interfaceando repository

Eu uso uma arquitetura de Repositorio com DomainStore. O repositorio escreve critérios de procura e delega ao DomainStore.
um exemplo seria

public final class RepositorioDocumento extends
		StandardEntityRepository<Documento> {

	public RepositorioDocumento() {
		super(Documento.class);
	}

	public Query<Documento> encontraPorPasta(Pasta pasta) {
		return this.getStorage().query(
				CriteriaBuilder.search(Documento.class).and("pasta").is(pasta)
				.orderBy("nome").desc()
				.all());
	}

	public Query<Documento> encontraPorReferencia(String referencia) {
		return this.getStorage().query(
				CriteriaBuilder.search(Documento.class).and("referencia").eq(referencia)
				.orderBy("nome").desc()
				.all());
	}

	public Query<Documento> encontraPorProjeto(Projeto projeto) {
		return this.getStorage().query(
				CriteriaBuilder.search(Documento.class).and("projeto").is(projeto)
				.orderBy("nome").desc()
				.all());
	}
}
sergiotaborda

Rubem Azenha:
Aliás, Sérgio, agora que eu vi que você linkou o blog do Guilherme Chapiewski, eu já tinha lido esse post na época que ele postou (é um dos blogs que eu “assino” o feed) e acho que você não deve ter lido até o final do mesmo:

(o grifo é meu)

Eu li até ao final sim. Ele está dizendo que os conceitos são parecidos. No meu dicionário "parecido’ significa “diferente que dá a ilusão de semelhante”. Ou seja, são na realidade diferentes. “interface do repositorio” não significa que vc declara “public interface Repository” é uma referencia ao contrato do repositorio. A frase pode ler-se como “(…) busca e persistência de objetos usando o contrato do Repository que tem o compromisso de ser mais semântico do que a do DAO”

É detalhes. Mas é no detalhes que está a diferença.

Marcio_Duran

:thumbup: “Uma ótima explicação e rica em informação” Parabéns Sérgio, esclareceu muita coisa mesmo !!!

T

[size=18][color=blue]Prezados,

Buscos um sistema que ao ser executado e/ou instalado em um ponto de uma rede possa trazer a informação
de cada maquina nesta rede - nome da maquina, ip, configuração, sistema operacional etc. E que tambem me
possibilite renomear esta maquina na rede, mudar ip e ate mesmo dá atributos. Desejo comprar sistema e codigo fonte. Interessados entrar em contato por email: [email removido] {tambem é msn}

Desde ja agradeço.[/color][/size]

T

Prezados,

Buscos um sistema que ao ser executado e/ou instalado em um ponto de uma rede possa trazer a informação
de cada maquina nesta rede - nome da maquina, ip, configuração, sistema operacional etc. E que tambem me
possibilite renomear esta maquina na rede, mudar ip e ate mesmo dá atributos. Desejo comprar sistema e codigo fonte. Interessados entrar em contato por email: [email removido] {tambem é msn}

Desde ja agradeço.

F_io_Henrique

:shock:

Criado 25 de janeiro de 2009
Ultima resposta 12 de fev. de 2009
Respostas 45
Participantes 13