Dúvidas arquiteturais - DDD, Repository, Camadas

Olá, tenho algumas dúvidas que não me deixam mais durmir… hummmmmmmmm, ok eu durmo sim vai, mais ainda tenho as dúvidsa hehe.

Seguinte, muito se fala e eu concordo plenamente sobre:

  • “não utilizar get e set apenas para colocar e recuperar dados do objeto, ao invés disso tenha objetos inteligentes que manipulão seu próprio estado”;
  • “comunicação entre camadas devem seguir uma hierarquia e para não “pular” camadas”;
  • “DDD e o conceito de repository”.

Bem em cima disso eis minhas dúvidas que eu gostaria muito de saná-las de uma vez por todas:

1. Comunição entre camadas: Muitos projetos em que participo e participei utilizam uma estrutura mais ou menos da seguinte maneira [Visualização (com JSF por exemplo, etc), Negócio (com EJB como infraestrutura por exemplo) e Persistência (com Hibernate e JPA)]. Eis o que cada camada continha e o funcionamento.

VISUALIZAÇÃO: Aqui tinha todas as minhas paginas ou interfaces de interação com clientes;
NEGÓCIO: Ficavam meus EJBs que executavam as regras de negócio, e realizavam inclusive a persistência; [b]PERSISTÊNCIA[/b]: Nessa camada apesar do nome, não era quem realizava a persistência, apenas continham entidades e POJOS que eram utilizados como VOs apenas para trazer dados da VISUALIZACAO para o negócio efetuar ações sobre eles, geralmente classes para os telas de consulta da VISUALIZACAO encher de dados para a camada de NEGOCIO processar que eram os chamados CRITERIA de busca;

Alguns projetos fugiam dessa estrutura, porém a maioria era assim, estou muito incomodado com a forma que ela funciona, por exemplo vi alguns artigos do Shoes que são ótimos por sinal, falando que as camadas devem se comunicar com a sua camada abaixo somente e não quebrar a hierarquia de camadas, e que a lógica de negócio devem ficar nos objetos de domínio e não para servirem apenas como struct, como no C. Acredito que essa estrutura em que trabalhei nada tem de OO, e se parece muito com programação procedural.

Bem nessa estrutura que descrevi, a visualização tinha uma dependência com a camada de PERSITENCIA, por que as telas colocavam os dados direto dentro da entidade, que por sua vez eram encaminhadas para a camada de NEGÖCIO, isso forçava a inclusão de get e set nas entidades devido a exigência dos frameworks web, e nisso surgem minhas dúvidas:

  • Como resolver isso? crio objetos POJOS apenas para popular na camada de VISUALIZACAO e lá no NEGOCIO eu crio meu objeto de dominio com as informações?
  • Qual a solução mais inteligente para isso?
  • Como tirar essa dependência da VISUALIZACAO com a PERSISTENCIA.

2. DDD e repository: Já vi e percebi a vantagens do DDD e como podemos ter objetos bem mais inteligente, encapsulados etc, mais tenho uma duvida, de como ficaria a estrutura na interação do objeto de domínio com o Repository. Até onde si o Repository fornece serviços externos ao meu objeto de domínio por exemplo, no meu objeto de domínio Usuário eu teria um repository para ele, sei lá UsuarioRepository da vida, que forneceria por exemplo metodos para consultar alguma coisa em um banco de dados ou executar alguma ação fora do objeto de domínio. Ai surge as dúvidas hehe:

  • É essa a idéia que eu entendi mesmo do Repository?
  • Como ficaria isso no código, seria algo como:
@Entity
public class Usuario{
    
         @EJB
         private UsuarioRepository repository;

         public void save(){
                  //Regra de negócio entraria aqui por exemplo
                  repository.save(this);
         }

}
  • Se não for isso, como funcionaria esta idéia?

Bom acredito que a partir dessa dúvidas respondidas poderei formular outras que tenho, espero que o pessoal contribua

Obrigado

Acredito que os assuntos já fora debatidos, mas você pode fazer uma pesquisa no proprio GUJ na certa terá varios caminhos para solver suas duvidas.

a primeira pergunta que te faço é por que vc usa EJB? quais os motivos…

pelo seu relato vi que vc usa para separar a tal “camada de negocio”, e essa ja seria a 1a coisa a tirar. faca um modelo rico (nao anemico) sem separar logica de negocios dos dados. (é o que diz o artigo do shoes sobre objetos fantoches que deve ser o que vc leu)

uma coisa importante aqui eh que o padrao DTO (antes chamado de VO) só deve ser usado para transferencia de dados entre camadas “fisicas” (tiers). se vc nao tem objetos remotos, comunicacao de rede etc, nao use essa separacao de DTO/BO e nao use EJB.

outra coisa que reparei é vc usando EJB mesmo qdo falou de repositorios, e me pareceu que usou isso por causa da injecao de dependencia com @EJB. se nao tiver um motivo mais forte para usar EJB, largue disso e use um container IoC mais completo, robusto e simples como spring, guice ou picocontainer.

agora sobre as camadas: essa coisa de separacao de camadas eh complicada. qdo falamos de camadas “logicas” (layers) é impossivel ter a separacao total entre as camadas. exemplo: vc divide uma camada de Apresentacao/View e uma camada pro modelo. por mais separadas que estejam, o dia que precisar acrescentar um campo novo tem que mudar a view, o model, o DAO, criar a coluna no banco etc. eh bom separar? sim, obviamente. mas cuidado pra nao cair na armadilha de ficar louco tentando separar tudo 100% que isso eh impossivel.

por ultimo, um comentario sobre o repositorio: nao necessariamente vc precisa de um metodo save dentro da entidade para usar repositorio (alias, metodos de persistencia dentro da entidade sao mais proximas do padrao Active Record do que de repository propriamente dito). a ideia do repositorio eh encapsular a nocao de persistencia para que seu domain model nao se preocupe com isso

Esse site eu achei interessante o mesmo visa um aspecto diferenciado sobre DDD, e acredito que até melhor conceituado no que realmente cabe seu uso.

ROMULUS proposal is based on recognising some of the deficiencies of standard Java Enterprise Edition, and proposing a new paradigm for developing web applications taking advantage of new trends in software engineering, such as domain driven design combined with agile development methodologies, and some of the principles from Ruby on Rails.

http://www.ict-romulus.eu/web/romulus

Criar objetos especias para a visualização é uma opção. Em sistema desktop é até uma necessidade se a sua tela for muito complexa. Em todos os sistemas pode simplificar a carga.
Tenha sempre em mente que os objetos de entidade são omnipresentes. Eles são manpulados por quase todas as camadas. Serem beans (não java beans, beans apenas , como get/set) é um padrões normal já que esses objetos são normalmente apenas sacos de propriedades ( PropertyBags)

Essas é uma das possibilidades. Normalmente as operações que alteram o estado do sistema ( diferente de estado do objeto) não ficam no objeto. mas vc poderia ter algo assim :

public class User{

     @EJB
     private ProfileRepository repository;

     public Collection<Perfil> perfis(Boolean active){
            return  repository.findProfilesForUser(this, active);
     }

}

[/code]

Primeiramente agradeço a todos que contribuiram

Bem, a camada de negócio que falei não é apenas um projetinho que estou usando entre a VIEW e PERSISTÊNCIA, ele engloba vários componentes EJB, inclusive locais e remotos, então não esotu usando EJB só para regra de negócio, uso ele, pois o sistema exige alta escalabilidade, distribuição de cargas entre os componentes EJB, etc…

Estou ainda em dúvida com a questão de utilizar as entidades na VIEW, ou não, o que é melhor? usar a própria entidade para ser populada na VIEW, ou eu fazer isso de outra forma? e qual seria outra forma de fazer?

Com relação a DDD e o Repository, tenho ainda várias duvidas, mais estarei procurando fontes mais a fundo, estava mesmo em dúvida com relação a estrutura de código como ficaria, se poderia injetar mesmo o repository no dominio, etc…

Abraços

[quote=analyser]
Estou ainda em dúvida com a questão de utilizar as entidades na VIEW, ou não, o que é melhor? usar a própria entidade para ser populada na VIEW, ou eu fazer isso de outra forma? e qual seria outra forma de fazer?
Abraços[/quote]
:arrow: Navegabilidade versus comportamento, MVC (Model View Control), o que é pra apresentação não são as entidades de negocios, são especializações de comportamento funcional de API que trata desse assunto.Acho que o Sergio Tarboda mostrou bem isso.

otimo!

a resposta simples seria: sim, use as entidades direto na view sem problema algum (seria ma pratica criar uma especie de DTO pra jogar pra view)

mas ja que vc esta usando EJB, incluindo chamadas remotas, precisa pensar bem isso. as suas entidades estao disponiveis na view? ou quem mexe com persistencia sao os ejbs remotos? se as entidades estiverem só remotamente, acho bem dificil vc fazer os seus ejbs devolverem sempre as entidades e vc vai acabar precisando de uns DTOs aqui. mas repare que o DTO eh necessario por causa da comunicacao remota, nao por causa da view.

O que estamos chamando de entidades ?[color=blue]“mas ja que vc esta usando EJB, incluindo chamadas remotas, precisa pensar bem isso. as suas entidades estao disponiveis na view?”[/color]

Deixar o objeto ter responsabilidade ao dominio e não para infraetrutura o que for de responsabilidade ao encapsulamento é comportamento de serviço(Service interfaces/implementations) e controle(Controler Components).

Olá, sei que já faz um tempo que postei a dúvida, mais quero entender uma coisa ainda.

Não entendi a reposta do Marcio Duran quando ele fala de “Observações ao Objeto(Estado/Comportamento)”, o que vc quiz dizer quando falow em tirar o @Entity do objeto usuário, ele não será mais um entidade O/R?

Só uma resalva, quando citei o problema, não falei de um projeto que estou no momento, e sim de vários que participei, que estavam dessa forma, querendo saber sobre Má práticas nessa arquitetura :D, por isso as perguntas sobre meus ejbs remotos, são muito variadas, as vezes era entre a view e o negócio, e as vezes era entre componente ejbs mesmo.

Abraços

Analyser, não ligue se não entender o que o Duran disse… quase ninguém entende.
Gostei muito do tópico, tenho muitas dúvidas em relação aos assuntos abordados.
Notei uma semelhança absurda desse modelo descrito por você com uns projetos que trabalho, será que somos da mesma empresa? hehehe
Sei que separar 100% os tiers é impossível e nem devemos seguir isso, mas o que devemos ter em mente é a separação de responsabilidades, isso deve ser muito bem definido.
O que sinto muita falta nessa arquitetura é justamente essa separação de responsabilidades, há muita coisa dependente entre as camadas, o model não deveria depender da view, mas depende (exemplo: queries de consulta sendo montadas na view, sim, acreditem, entre outras coisas).
Outra coisa que sinto muita falta é um controler bem definido (muitas vezes ausente) e façades para interfacear a comunicação entre esses tiers, que é feito macarrônicamente.
O que uso mesmo e não vejo problema nenhum são os próprios objetos de entidades sendo populados na view e enviados ao model, não acho que faça muito sentido ficar recriando DTOs (muitas vezes confundidos com VOs,TOs, etc) na view só pra ter uma “independencia” entre as camadas.
Quanto a modelos anêmicos (!DDD) creioq ue não haja problemas nenhum em se fazer sacos de propriedades (DTOs, VOs, TOs, etc etc tec) que sejam meros structs de luxo pa representar a camada de persitência. Alguma objeção quanto a isso? Não há muito o que se fazer nesse caso, creio.

Enfim, tenho muito o que aprender! Quero ler mais, alguem poderia nos auxiliar?

[quote=Tchello] Analyser, não ligue se não entender o que o Duran disse… quase ninguém entende.
Gostei muito do tópico, tenho muitas dúvidas em relação aos assuntos abordados.
Notei uma semelhança absurda desse modelo descrito por você com uns projetos que trabalho, será que somos da mesma empresa? hehehe
Sei que separar 100% os tiers é impossível e nem devemos seguir isso, mas o que devemos ter em mente é a separação de responsabilidades, isso deve ser muito bem definido.
O que sinto muita falta nessa arquitetura é justamente essa separação de responsabilidades, há muita coisa dependente entre as camadas, o model não deveria depender da view, mas depende (exemplo: queries de consulta sendo montadas na view, sim, acreditem, entre outras coisas).
Outra coisa que sinto muita falta é um controler bem definido (muitas vezes ausente) e façades para interfacear a comunicação entre esses tiers, que é feito macarrônicamente.
O que uso mesmo e não vejo problema nenhum são os próprios objetos de entidades sendo populados na view e enviados ao model, não acho que faça muito sentido ficar recriando DTOs (muitas vezes confundidos com VOs,TOs, etc) na view só pra ter uma “independencia” entre as camadas.
Quanto a modelos anêmicos (!DDD) creioq ue não haja problemas nenhum em se fazer sacos de propriedades (DTOs, VOs, TOs, etc etc tec) que sejam meros structs de luxo pa representar a camada de persitência. Alguma objeção quanto a isso? Não há muito o que se fazer nesse caso, creio.

Enfim, tenho muito o que aprender! Quero ler mais, alguem poderia nos auxiliar?
[/quote]

Olá Tchello, rs acho interessante os comentários do Duran, só queria entender mesmo essa parte hehe, e no modelo que descrevi o model não depende da view, a view que depende do model, li alguns posts do Sergio Taborda no site dele que me esclareceu várias coisas, acho legal vc dar uma olhada tb.

Não sei de onde vc tirou isto. Sim deve separar 100% os tiers, e sim deve seguir isso.
Quando se fala em separar se fala sempre em separar responsabilidade, mas na prática isso significa
desde realocar classes para outros pacotes até reescrever camadas e alterar o interior das classes existentes.

Parece que vc ja sabe o que está errado. Agora vc precisa de um refactoring geral e menos se preocupar com DDD ou repositorios.

Na estrutura que citei, não existe queries de consulta sendo montadas na view, view é view, as queries de consultas são montadas no meu “repository” ou “DAO” da vida, que com certeza não fica na view, o problema que falei era dependẽncia por questão de entidade mesmo, para população na view e tal.

[quote=sergiotaborda][quote=Tchello]
Sei que separar 100% os tiers é impossível e nem devemos seguir isso
[/quote]

Não sei de onde vc tirou isto. Sim deve separar 100% os tiers, e sim deve seguir isso.
Quando se fala em separar se fala sempre em separar responsabilidade, mas na prática isso significa
desde realocar classes para outros pacotes até reescrever camadas e alterar o interior das classes existentes.
[/quote]

Acho que não estamos falando a mesma língua, mas foi exatamente o que disse: separar as responsabilidades.

Bem que eu gostaria, mas não tenho poder pra isso e a empresa não disponibilizaria pessoal nem recursos pra tal.
Resumindo: vai continuar a macarronada que ta.

[quote=analyser][quote=Tchello]
O que sinto muita falta nessa arquitetura é justamente essa separação de responsabilidades, há muita coisa dependente entre as camadas, o model não deveria depender da view, mas depende (exemplo: queries de consulta sendo montadas na view, sim, acreditem, entre outras coisas).
[/quote]

Na estrutura que citei, não existe queries de consulta sendo montadas na view, view é view, as queries de consultas são montadas no meu “repository” ou “DAO” da vida, que com certeza não fica na view, o problema que falei era dependẽncia por questão de entidade mesmo, para população na view e tal. [/quote]
Eu entendi, só usei como exemplo o caso que acontece comigo, que não existe nem DAO nem Repository, nem nada. Cada um que precisar de algo da persitência que se vira com banco.

[quote=Tchello]
Bem que eu gostaria, mas não tenho poder pra isso e a empresa não disponibilizaria pessoal nem recursos pra tal.
Resumindo: vai continuar a macarronada que ta.[/quote]

Se sua empresa não tem tempo pra refactoring esqueca essas coisas de OO, DDD e boas práticas. :wink: