Mais uma dúvida sobre Entites X Repositories dentro de DDD.  XML
Índice dos Fóruns » Arquitetura de Sistemas
Autor Mensagem
luizaso
Debugger
[Avatar]

Membro desde: 29/01/2003 10:00:19
Mensagens: 56
Localização: Belo Horizonte - MG
Offline

Pessoal, li muitas da discussões aqui no fórum sobre Entities X Repositories, algumas muito acaloradas rsrsrsrsrs... mas ainda persistiu uma dúvida. Na verdade eu sou desenvolvedor do mundo .NET mas sempre visito os fóruns aqui do GUJ, pois neles encontro muita informação interessante que ainda hoje não é muito divulgada entre desenvolvedores em plataforma MS.

Estou apenas iniciando na utilização de DDD e tenho uma dúvida simples mas que ainda não me foi esclarecida mesmo após horas de leitura nos posts sobre o assunto aqui no GUJ.

No .NET quando vamos fazer a separação de Layers utilizamos projetos de classes diferentes e uma limitação que existe nesse caso é que não pode haver referência circular entre dois projetos.

Com essa limitação em mente e entendendo que a arquitetura que tenho proposto para um projeto pessoal no qual estou trabalhando atualmente se constitui de um modelo básico parecido com:

[Aplicação]-> [DDD: Entities, Repositories, etc] -> [Infraestrtura: DAL -> NHibernate]

surge a seguinte dúvida:

Eu tenho uma Entity User, esta Entity pode fazer referência direta ao meu DAO para as operações básicas de CRUD, ou seria parte de DDD que as minhas Entities utilizem o Repository para estas operações?

Sei que é uma dúvida primária, mas primário é o estado em que estou na utilização de DDD.

Obrigado e abraços.

Luiz Alberberto da Silva Oliveira
Programador
Belo Horizonte - MG
[WWW] [MSN]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 719
Offline

Olá Luiz.
Domain-Driven trabalha com o domínio do software e isso não contempla classes "DAO"s, que é apenas um pattern de abstração da persistência dos seus dados:

http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

Repositories são dirigidos ao domínio e não a infraestrutura... ele esta (e faz parte) do domínio e se comunica com a camada de persistencia (normalmente DAOs Data Mappers):

http://martinfowler.com/eaaCatalog/repository.html

Independente disso, uma entidade não deveria conter repositórios apenas para satisfazer métodos CRUDs.
Um Usuário que contenha operações como salvar e apagar (ele mesmo), descaracteriza seu objeto como uma Entity de um Domain Model e o torna parte de outro padrão, o Active Record.

http://martinfowler.com/eaaCatalog/activeRecord.html

Em Domain-Driven, é o repositório que deve adicionar ou remover entidades e não ela própria (não rola Active Record), portanto retire estes métodos de sua entidade.

Repositórios são úteis dentro da entidade, mas em outros casos. As vezes é necessário que um método de negócio (e não um simples CRUD) de uma Entity armazene informações ou realize consultas em uma única lógica
Normalmente um Service utiliza mais informações do repositório do que uma Entity, mas isso varia de caso a caso.

This message was edited 1 time. Last update was at 24/03/2008 00:48:00


... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.org/

[Email] [MSN]
pcalcado
Moderador
[Avatar]

Membro desde: 08/03/2004 17:19:35
Mensagens: 5174
Localização: Sydney - Australia
Offline

Oi, Luiz,

Sua dúvida não é básica e nem é tão relacionada com Doain-Driven Design. Procure ler sobre Dependency Inversion Principle. Eu escrevi um artigo que fala sobre isso para uma Mundo Java ou Mundo .Net (não lembro qual) mas dentro da plataforma da Microsoft existe um ótimo livro: Agile Principles, Patterns, and Practices in C# . Esse livro é uma versão C# do livro anterior do Uncle Bob, que usa Java: Agile Principles, Patterns, and Practices.

Basicamente o mesmo conteúdo em linguagens diferentes.

Phillip Calçado "Shoes"
http://fragmental.tw/
http://blog.fragmental.com.br/
"It is unfortunate that much of what is called 'object-oriented programming today is simply old style programming with fancier constructs." - Alan Kay
[Email] [WWW] [Yahoo!] [MSN]
pcalcado
Moderador
[Avatar]

Membro desde: 08/03/2004 17:19:35
Mensagens: 5174
Localização: Sydney - Australia
Offline

Lezinho wrote:
Um Usuário que contenha operações como salvar e apagar (ele mesmo), descaracteriza seu objeto como uma Entity de um Domain Model e o torna parte de outro padrão, o Active Record.

http://martinfowler.com/eaaCatalog/activeRecord.html

Em Domain-Driven, é o repositório que deve adicionar ou remover entidades e não ela própria (não rola Active Record), portanto retire estes métodos de sua entidade.

Repositórios são úteis dentro da entidade, mas em outros casos. As vezes é necessário que um método de negócio (e não um simples CRUD) de uma Entity armazene informações ou realize consultas em uma única lógica
Normalmente um Service utiliza mais informações do repositório do que uma Entity, mas isso varia de caso a caso.


Não exatamente. Active Record está relacionado ao Data Mapper, uma Camada abaixo do Domínio. Um AR pode ser um Entity sem problemas e não é porque você não usa um padrão descrito em Domain-Driven Design que você não está usando Domain-Driven Design.

Phillip Calçado "Shoes"
http://fragmental.tw/
http://blog.fragmental.com.br/
"It is unfortunate that much of what is called 'object-oriented programming today is simply old style programming with fancier constructs." - Alan Kay
[Email] [WWW] [Yahoo!] [MSN]
le-silva
Java Ninja
[Avatar]

Membro desde: 31/01/2003 10:21:32
Mensagens: 260
Offline

Oi Luiz, um livro interessante sobre DDD com exemplos em C#...

Applying Domain-Driven Design and Patterns: With Examples in C# and .NET
http://www.amazon.com/Applying-Domain-Driven-Design-Patterns-Examples/dp/0321268202

Leandro Silva

{ :blog => 'leandrosilva.com.br' , :twitter => '@codezone' }
[Email] [WWW]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 719
Offline

Shoes wrote:Um AR pode ser um Entity sem problemas e não é porque você não usa um padrão descrito em Domain-Driven Design que você não está usando Domain-Driven Design.


Uma entidade com responsabilidades de persistencia é uma salada de conceitos. Ela pode continuar sendo uma Entity, mas ao meu ver, mal modelada. Afinal de contas, o repository esta aí pra isso ...

This message was edited 1 time. Last update was at 24/03/2008 11:38:33


... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.org/

[Email] [MSN]
luizaso
Debugger
[Avatar]

Membro desde: 29/01/2003 10:00:19
Mensagens: 56
Localização: Belo Horizonte - MG
Offline

Fala galera, obrigado pelas respostas até agora, está sendo muito esclarecedor.

Lezinho, apenas para esclarecer, se eu tenho uma entity que possui seus próprios métodos CRUD, se esta chama o Repositório para se auto-persistir, ainda assim seria incorreto de acordo com sua visão, ter esses métodos em minha Entity?

E se não for assim, ou seja decidi por não ter o CRUD em minhas Entities, no caso quando precisar persistir uma Entity, eu deveria faze-lo no meu Cliente (entenda-se por cliente, uma Fachada ou mesmo a minha aplicação) utilizando algo parecido com:



Mesmo assim ainda não estou convencido de qual o melhor e mais prático modelo a ser utilizado se entities com ou sem CRUD, mas gostaria de entender melhor sua visão.

Em meus estudos sobre DDD, não vi nenhum restrição em uma entity ter o CRUD em si, mas como a discussão sempre é esclarecedora, quero entender melhor cada um dos pontos aqui abordados.

Apenas para título de informação, se em meu projeto .NET eu decido manter em dois projetos diferentes os meus Repositories e meus Entities, crio um problema de referência, pois meu projeto Repositories precisa referênciar o projeto de Entities e o projeto de Entities, se precisar de um Repository, vai ter que referênciar Repositoreis, o que cria uma referência circular não aceita pelo .NET (como sitei em meu primeiro post), mesmo usando de Interfaces não consigo ver uma solução para isso, caso eu queira realmente manter as coisas em Assemblies separados.

This message was edited 1 time. Last update was at 24/03/2008 12:42:54


Luiz Alberberto da Silva Oliveira
Programador
Belo Horizonte - MG
[WWW] [MSN]
gibaholms
JavaTeenager
[Avatar]

Membro desde: 13/11/2007 13:37:48
Mensagens: 151
Localização: Santos - SP
Offline

Oi cara.. na minha empresa trabalho também com .NET e temos este mesmo problema de referencia ciclica...

ai usamos um domain model que tem um certo overhead, pois criamos uma VO apenas para trafegar informação da camada de dominio pra camada de persistencia...

um cara aki estava propondo uma solução com reflection, ficava mto boa... evitava a referencia ciclica (pq vc referencia o objeto a partir do proprio assembly) e evitava o overhead de replicar as propriedades do dominio pra VO... a unica coisa ruim eh a complexidade mesmo, mas com umas factories acabou ficando bem legal

SCJA 1.0 | SCJP 4 | SCWCD 5 | SCBCD 5 | Oracle Weblogic Portal 10g Developer
[WWW] [MSN]
le-silva
Java Ninja
[Avatar]

Membro desde: 31/01/2003 10:21:32
Mensagens: 260
Offline

Entities e Repositories fazem parte da mesma layer, a de domínio. Então, não há a necessidade de você colocá-las em projetos separados. Aliás, todo o teu aplicativo pode estar no mesmo projeto, tendo apenas uma divisão clara de layers.

Sobre a persistencias de suas entidades, é exatamente assim como você citou - Repository.add(entity). A único detalhe que acho que vale a pena citar, é que normalmente usamos termos pros métodos de repositório diferentes do que usamos em DAOs. Geralmente, em repositório:

- add
- remove
- update ou merge
- get

Porque esses termos abstraem um pouco mais a idéia de repositório, que não necessáriamente é um banco de dados relacional. Mas isso não é uma regra!

Abraço!

Leandro Silva

{ :blog => 'leandrosilva.com.br' , :twitter => '@codezone' }
[Email] [WWW]
le-silva
Java Ninja
[Avatar]

Membro desde: 31/01/2003 10:21:32
Mensagens: 260
Offline

Exemplo extraído do livro que te indiquei (capitulo 6):


Leandro Silva

{ :blog => 'leandrosilva.com.br' , :twitter => '@codezone' }
[Email] [WWW]
Laércio Queiroz
Thread.start()
[Avatar]

Membro desde: 31/07/2007 16:49:08
Mensagens: 32
Localização: Salvador - BA
Offline

luizaso wrote:
Apenas para título de informação, se em meu projeto .NET eu decido manter em dois projetos diferentes os meus Repositories e meus Entities, crio um problema de referência, pois meu projeto Repositories precisa referênciar o projeto de Entities e o projeto de Entities, se precisar de um Repository, vai ter que referênciar Repositoreis, o que cria uma referência circular não aceita pelo .NET (como sitei em meu primeiro post), mesmo usando de Interfaces não consigo ver uma solução para isso, caso eu queira realmente manter as coisas em Assemblies separados.


Olá luizaso,

Eu postei algo sobre esse problema de referências cíclicas do .NET em meu blog. Eu sempre vi isto como um problema de design, mas gostaria aber a opinião de vcs...

[]s

Laércio Queiroz
http://laercioqueiroz.wordpress.com
[Email] [WWW] [MSN]
Mauricio Linhares
Moderador
[Avatar]

Membro desde: 09/01/2005 23:28:22
Mensagens: 3717
Localização: João Pessoa, Paraíba - Brasil
Offline

Lezinho wrote:
Shoes wrote:Um AR pode ser um Entity sem problemas e não é porque você não usa um padrão descrito em Domain-Driven Design que você não está usando Domain-Driven Design.


Uma entidade com responsabilidades de persistencia é uma salada de conceitos. Ela pode continuar sendo uma Entity, mas ao meu ver, mal modelada. Afinal de contas, o repository esta aí pra isso ...


Repositories não são a única forma de se modelar o acesso a fontes de dados, AR em linguagens "duras" como Java realmente é horrível (eu fiz uma vez usando introduções do AspectJ mas não me agradei muito do resultado não), mas quando você passa pra uma linguagem com menos burocracia AR deixa o código bem mais simples e ainda tem a vantagem de ser uma classe a menos, afinal os métodos do repositório são todos stateless, se transformam num monte de métodos estáticos na classe do AR.

Não acho que AR torne uma entidade mal modelada, até porque as implementações de AR que eu tive contato até agora são bem menos poluentes que os métodos comuns de persistência em Java como o uso de annotations.

Meu blog sobre desenvolvimento | My Last.fm | @mauriciojr

Screencast de Introdução a linguagem Objective-C
[WWW]
cmoscoso
Virtual Machine Man

Membro desde: 23/10/2007 10:08:29
Mensagens: 687
Offline

luizaso wrote:
E se não for assim, ou seja decidi por não ter o CRUD em minhas Entities, no caso quando precisar persistir uma Entity, eu deveria faze-lo no meu Cliente (entenda-se por cliente, uma Fachada ou mesmo a minha aplicação)...


Sim. Vc tb pode usar domain services pra isso e apesar de ser menos comum, até pode ser feito dentro da propria entity. O importante é que seja feito delegando ao repositorio.

luizaso wrote:
Apenas para título de informação, se em meu projeto .NET eu decido manter em dois projetos diferentes os meus Repositories e meus Entities, crio um problema de referência, pois meu projeto Repositories precisa referênciar o projeto de Entities e o projeto de Entities, se precisar de um Repository, vai ter que referênciar Repositoreis, o que cria uma referência circular não aceita pelo .NET (como sitei em meu primeiro post), mesmo usando de Interfaces não consigo ver uma solução para isso, caso eu queira realmente manter as coisas em Assemblies separados.


Você pode separar seu dominio em diferentes projetos mas nao deve faze-lo utilizando criterios tecnicos como o tipo do objeto (entities, repositorios, services, ...). Isso vai te levar a codigo com alto acoplamento e baixa coesao (vide Uncle Bob).

Eric Evans sugere que organizemos nosso dominio em modulos (pacotes em java e namespaces em .net) utilizando criterios conceituais do dominio, fazendo com que a estrtura de pacotes contribua para a UBIQUITOUS LANGUAGE.

Isso porque referencias cruzadas devem ser evitadas em todos os niveis, inclusive entre modulos.
[Email]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 719
Offline


Lezinho, apenas para esclarecer, se eu tenho uma entity que possui seus próprios métodos CRUD, se esta chama o Repositório para se auto-persistir, ainda assim seria incorreto de acordo com sua visão, ter esses métodos em minha Entity?



Do meu ponto de vista você esta dando voltas desnecessárias. Um repositório armazena informações, correto? Por que colocar mais este método identico na entidade (os CRUDs)? Apenas para delegar para o repositório? Qual o ganho disso?

Uma entidade tenta representar algo de seu domínio, ela tem o comportamento pertinente a sí. Esta entidade é armazenada em algum lugar, um repositório de dados, que é outro objeto de negócio.

Se uma entidade faz uso de um repositório de dados em seu método de negócio, faz sentido ela solicitar a ajuda de um repositório. Contudo não faz sentido a entidade assumir o papel de um repositório de dados, atuando só como uma fachada, sendo que já existe um repositório pra isso (e tanto um como outro pertencem a mesma camada de negócio).


E se não for assim, ou seja decidi por não ter o CRUD em minhas Entities, no caso quando precisar persistir uma Entity, eu deveria faze-lo no meu Cliente (entenda-se por cliente, uma Fachada


... isso faz mais sentido do que você sugeriu no princípio. Segue anexo o popular diagrama de uma "Layered Architecture" retirada do Domain-Driven Design. Veja que tanto a layer Application e até mesmo a UI pode acessar o domain, o que não se pode é o contrário (Repositório tbm é domain).
[Thumb - LayeredArchitecture .jpg]
 Nome do arquivo LayeredArchitecture .jpg [Disk] Download
 Descrição Layered Architecture
 Tamanho 36 Kbytes
 Baixado:  137 vez(es)

This message was edited 1 time. Last update was at 24/03/2008 13:25:07


... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.org/

[Email] [MSN]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 719
Offline

Maurício Linhares wrote:
Lezinho wrote:
Shoes wrote:Um AR pode ser um Entity sem problemas e não é porque você não usa um padrão descrito em Domain-Driven Design que você não está usando Domain-Driven Design.


Uma entidade com responsabilidades de persistencia é uma salada de conceitos. Ela pode continuar sendo uma Entity, mas ao meu ver, mal modelada. Afinal de contas, o repository esta aí pra isso ...


Repositories não são a única forma de se modelar o acesso a fontes de dados, AR em linguagens "duras" como Java realmente é horrível (eu fiz uma vez usando introduções do AspectJ mas não me agradei muito do resultado não), mas quando você passa pra uma linguagem com menos burocracia AR deixa o código bem mais simples e ainda tem a vantagem de ser uma classe a menos, afinal os métodos do repositório são todos stateless, se transformam num monte de métodos estáticos na classe do AR.

Não acho que AR torne uma entidade mal modelada, até porque as implementações de AR que eu tive contato até agora são bem menos poluentes que os métodos comuns de persistência em Java como o uso de annotations.



Concordo que é uma classe a menos, Mauricio, mas temos que ponderar se isso é ganho ou não. Repositório é tbm classe de negócio, tão quanto é uma entidade, eu acredito nesse valor agregado.

É claro que tbm se deve preservar o bom senso. Jamais iria ingorar AR usando RoR simplesmente por achar que o design fica melhor separando mais responsabilidades.

... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.org/

[Email] [MSN]
 
Índice dos Fóruns » Arquitetura de Sistemas
Ir para:   
Powered by JForum 2.1.8 © JForum Team