Dependencia entre as camadas

29 respostas
AGAraujo

Galera estou com uma dúvida sobre a questão de dependência entre as camadas.

Eric Evans, em seu livro, diz que devemos utilizar os padrões citados no seu livro para resolver problemas de dependencia entre camadas, entre outros.

A ideia é manter a dependencia entre as camadas superiores com as inferiores.

Para tanto fico agora numa duvida que vou expressar com um exemplo.

[CAMADA DE DOMINIO]

public class User implements IEntity{
...
}


public class IUserRepository {
  public save(IEntity i);
}

[CAMADA DE INFRAESTRUTURA]

/*assinatuas das entitdades*/
public class IEntity {
  public Integer getId();
}

/*implementação do repositorio*/
public class UserRepositoryImpl implements IUserRepostory{
  public save(IEntity i){
    ...
  }
}

Ao meu ver estou mantendo a ideia de dependencia de cima para baixo, porém como posso passar o estado do meu objeto sem conhecê-los?
ou seja, como posso fazer o código abaixo sem conhecer a entidade concreta?

public save(IEntity i){
  String sql = "insert into (id, username, password) values(?,?,?)";
  ... = ((User) i).getId(); 
  ... = ((User) i).getUsername(); 
  ... = ((User) i).getPassword(); 
  ...
}

Desde já agradeço as dicas e comentários.

29 Respostas

tnaires

Uma sugestão: elimine essa interface IEntity. Além de não ter nenhuma razão pra ela existir, você ainda tá forçando todas as suas entidades a ter uma chave primária do tipo Integer e, de quebra, tá tendo que fazer todos esses casts chatos no código cliente.

Se você passar diretamente a entidade concreta ao invés dessa interface seus problemas estão resolvidos.

AGAraujo

Valeu cabra…

Bom, gostaria de discutir um pouco o que você escreveu.

A objetivo é este mesmo, deixar todas as entidades com um ID do tipo INTEGER, então quanto a isto não posso mudar. Bom…mas mesmo que eu não tenha isto, eliminar IEntity, elimina a dependência entre a camada de infraestrutura e a camada de dominio?

Se puder, você ou outros que concordem com isto poderia me explicar melhor, pois não consigo ver a eliminação dessa dependencia com esta ação. Ou seja, não vejo meus problemas resolvidos!! rsrs.

Para mim a camada de infraestrutura continua mais dependente ainda da camada de dominio. Estou errado?

Desde de já, agradeço sua colaboração.

tnaires

E se você tiver uma chave composta? Ou se tiver uma chave cujo valor fique acima do limite máximo de um Integer?

AGAraujo:
Bom…mas mesmo que eu não tenha isto, eliminar IEntity, elimina a dependência entre a camada de infraestrutura e a camada de dominio?

Se puder, você ou outros que concordem com isto poderia me explicar melhor, pois não consigo ver a eliminação dessa dependencia com esta ação. Ou seja, não vejo meus problemas resolvidos!! rsrs.

Para mim a camada de infraestrutura continua mais dependente ainda da camada de dominio. Estou errado?


O seu problema é que o repositório não conhece os detalhes da entidade a ser persistida, certo? Por que você não passa logo a entidade ao invés da interface IEntity? Isso resolve tudo.

E, pelo que vi no seu outro post, você está partindo do princípio errado. Repositório não é da infra, é do domínio. Um repositório precisa conhecer os detalhes da entidade que ele persiste.

AGAraujo

Eu entendi você. O lance é que quanto a isto não há como mudar, considere uma exigência e vamos em frente. rsrs

Bom pode ser que realmente esteja partindo errado… então vamos a algumas concordâncias:

  • Repositorio é do DOMINIO e sua implementação é da INFRA
  • O Repositorio precisa conhecer sua entidade correspondente, no caso User e todos pertencem ao DOMINIO

Ai vem onde posso estar enganado e se tiver e puder me ajudar com isto eu agradeço:

  • Quando implemento o repositorio na INFRA, consequentemente eu crio uma dependencia da INFRA com relação ao DOMINIO, pois agora terei que fazer a INFRAESTRUTURA conhecer USER que é parte do dominio. Estou errado com este pensamento?

Vlw de novo

sergiotaborda

Lá vamos nós de novo…

Entidades e Repositorio pertencem na mesma camada. Portanto não ha nenhum problema

[CAMADA DE DOMINIO]

public class User{
...
}

public abstract  class AbstractRepository<T> {
    
    public abstract save((T obj);
} 

public class UserRepository  extends AbstractRepository<User>{
  public save(User i){
        // ler campos 
  }
}
  1. nomes de interfaces não começam com I. Essa nomenclatura não é usada em java nem em OO em geral.
  2. Usar uma interface para todas as entidades não é o problema (isso é um padrão chamado Layer SuperType) o problema é que getID retorne Integer. getID deve retornar um Object. Ou um tipo especifico de identificadores como Identifier que tem várias implementações como Integeridentifier, etc…

Identificadores podem ser inteiros, long, datas e strings. usar sempre inteiro não é boa ideia.

tnaires

Aqui no GUJ não há um consenso sobre isso. Há pessoas que escrevem um DAO na infra como implementação do repositório situado no domínio. Não sei se estou certo, mas eu deixo as implementações do repositório no próprio domínio.

Isso.

AGAraujo:
Ai vem onde posso estar enganado e se tiver e puder me ajudar com isto eu agradeço:

  • Quando implemento o repositorio na INFRA, consequentemente eu crio uma dependencia da INFRA com relação ao DOMINIO, pois agora terei que fazer a INFRAESTRUTURA conhecer USER que é parte do dominio. Estou errado com este pensamento?

Isso depende da sua opção. Se você escrever a implementação do repositório na camada de infra-estrutura, terá um enorme trabalho pra evitar essa dependência, se fizer questão de eliminá-la é claro.

Outra coisa que você pode fazer é empacotar por feature, não por camada. Isso significa colocar tudo que envolva um cadastro de clientes, por exemplo - Cliente, ClienteRepository, ClienteService, ClienteQualquerCoisa - em um único pacote chamado cliente. Cada funcionalidade da aplicação fica sendo uma API separada. Fiz essa experiência uma vez e achei interessante.

AGAraujo

Não entendi! O que não é problema?

Valeu pela explicação!

tnaires

Sérgio, por favor pare com essa mania de responder ignorando tudo o que as outras pessoas já responderam no tópico. Você falou coisas que eu já tinha falado antes. Se eu errei, pelo menos aponte para eu aprender também.

AGAraujo

rs. nem vou tentar entrar nesta discussão… eu ein!! rs. blz… até ok tb.

Mas isto não foge da ideia de DDD?
Bom ao que sei, foge, e se fugir não resolve o problema que estou metido. rsrs

tnaires

Em minha opinião não. Separar em camadas não é necessariamente igual a separar em pacotes. O importante é não misturar as responsabilidades das classes.

AGAraujo

Em minha opinião não. Separar em camadas não é necessariamente igual a separar em pacotes. O importante é não misturar as responsabilidades das classes.

Concordo com a ideia de não misturar as responsabilidades… mas não entendi sua coloção sobre camadas e pacotes. O que os pacotes tem haver com a arquitetura, conceitualmente falando? (talvez seja uma pergunta boba, mas é sobre para entender mesmo)

tnaires

O seu problema, pelo que eu entendi, inclui, mas não está limitado a, manter o repositório e a entidade dentro do mesmo pacote para que esta seja conhecida por aquele. Há duas formas de fazer isso:

  • mantendo a implementação do repositório dentro do domínio, partindo do princípio que você está criando um pacote por camada para organizar as classes;
  • empacotar po feature, não por camada. Foi só uma sugestão que pouco tem a ver com o tópico realmente.
AGAraujo

O seu problema, pelo que eu entendi, inclui, mas não está limitado a, manter o repositório e a entidade dentro do mesmo pacote para que esta seja conhecida por aquele. Há duas formas de fazer isso:

  • mantendo a implementação do repositório dentro do domínio, partindo do princípio que você está criando um pacote por camada para organizar as classes;
  • empacotar po feature, não por camada. Foi só uma sugestão que pouco tem a ver com o tópico realmente.

blz cabra… esquenta não!! a sugestão é bem vinda só quis entender seu raciocínio.

bom… voltando…

Eu pensei realmente em implementar o repositorio no dominio, garantindo assim a dependencia como diz que deve ser o Evans.
O lance é que o próprio Evans criou uma implementação diferente no seu exemplo (DDD Sample Application)… causando dependencia da infraestrutura para a camada de dominio, o que, NA MINHA VISÃO, vai contra o que ele mesmo prega!

O que você acha?

sergiotaborda

Eu falei de propósito. Para reforçar o que vc escreveu… Eu não ignorei, eu li tudo e repeti. Repetição é uma forma de levaras pessoas a entender. Se vc tivesse errado, vc sabe que eu tinha dito. Vc ficou chateado porque eu disse o mesmo que vc ? vc quer diga coisas diferentes da verdade ? hum… já sei… vc está chateado porque não lhe dei crédito pela verdade.

Caro, AGAraujo é exactamente como o tnaires falou. Ouça o que ele falar porque é verdade.

(Se não for estou cá para lhe puxar as orelhas… lololololololol )

AGAraujo

Eu falei de propósito. Para reforçar o que vc escreveu… Eu não ignorei, eu li tudo e repeti. Repetição é uma forma de levaras pessoas a entender. Se vc tivesse errado, vc sabe que eu tinha dito. Vc ficou chateado porque eu disse o mesmo que vc ? vc quer diga coisas diferentes da verdade ? hum… já sei… vc está chateado porque não lhe dei crédito pela verdade.

Caro, AGAraujo é exactamente como o tnaires falou. Ouça o que ele falar porque é verdade.

(Se não for estou cá para lhe puxar as orelhas… lololololololol )

Blz Sergio, vlw pelo help! Só não tinha entendido, e possivelmente o tnaires também não entendeu, o que você quis dizer!

E se puder contribuir também, acho ótimo…

tnaires

A qual parte do livro você está se referindo exatamente? Não lembro de ter visto isso no livro, mas posso estar errado!

De qualquer forma, eu sempre tento construir a infraestrutura independente do domínio, ela deve apenas oferecer serviços para outras camadas usarem conforme necessário. Se isso ocorrer, eu investigarei se há algum problema de coesão no design. Mas se eu verificar que é realmente necessário, fazer o quê…

tnaires

sergiotaborda:
Vc ficou chateado porque eu disse o mesmo que vc ? vc quer diga coisas diferentes da verdade ? hum… já sei… vc está chateado porque não lhe dei crédito pela verdade.

Caro, AGAraujo é exactamente como o tnaires falou. Ouça o que ele falar porque é verdade.

(Se não for estou cá para lhe puxar as orelhas… lololololololol )


Hehehe :oops:, realmente poderia ter dito o que disse de forma mais suave. Peço desculpas.

Só queria que você citasse quando repetisse algo que alguém disse, porque a impressão que dá é que você está ignorando todas as contribuições anteriores e começando do zero. Mas já entendi que sua intenção não foi essa.

AGAraujo

A qual parte do livro você está se referindo exatamente? Não lembro de ter visto isso no livro, mas posso estar errado!

De qualquer forma, eu sempre tento construir a infraestrutura independente do domínio, ela deve apenas oferecer serviços para outras camadas usarem conforme necessário. Se isso ocorrer, eu investigarei se há algum problema de coesão no design. Mas se eu verificar que é realmente necessário, fazer o quê…

Falo do projeto que ele criou para demonstrar a implementação de DDD: http://dddsample.sourceforge.net/ e sua definição sobre dependencia entre camadas:

Esta citação também está no seu livro.

tnaires

Realmente, está claro que ele colocou as implementações na camada de infra. Nesse caso, há uma dependência da infra em relação ao modelo sim. E ela não está em consonância com a definição de camada transcrita por você.

Mas agora outra questão: essa nuance é tão importante? Deixe a infra depender do domínio e seja feliz :smiley:

AGAraujo

Realmente, está claro que ele colocou as implementações na camada de infra. Nesse caso, há uma dependência da infra em relação ao modelo sim. E ela não está em consonância com a definição de camada transcrita por você.

Mas agora outra questão: essa nuance é tão importante? Deixe a infra depender do domínio e seja feliz :D

É… e agora quem pode nos ajudar a explicar este fato, ou posso imaginar que o Evans errou na sua definição? (tive até medo de postar isto, rs)

sergiotaborda

Realmente, está claro que ele colocou as implementações na camada de infra. Nesse caso, há uma dependência da infra em relação ao modelo sim. E ela não está em consonância com a definição de camada transcrita por você.

Mas agora outra questão: essa nuance é tão importante? Deixe a infra depender do domínio e seja feliz :D

É… e agora quem pode nos ajudar a explicar este fato, ou posso imaginar que o Evans errou na sua definição? (tive até medo de postar isto, rs)

Engraçado essa situação. Para vc o Evans é algum tipo de deus e vc tem medo que ele o castigue ou que os seus seguidores o castiguem…

Ter uma infra independente do dominio não é trivial. Vc precisa de uma plataforma de aplicação inteira para isso. Existem tecnicas mais simples não totalmente independente e um dessas - a mais simples de todas- foi a que ele usou.

Coesão e acoplamento cada um toma quanto quer. Ele decidir acoplar. Se vc não quer acoplar vc não acopla. simples assim.
Só que vc vai ter que arranjar um jeito. Vc vai ter que estudar mais que simples DDD. Vc precisa de OO.

AGAraujo

Sergio, você não tem senso de humor apurado…
Bom…de nada tem haver com medo… estou apenas tentando ser “leve” nos comentários para evitar discussões desnecessárias.

Voltando ao DDD, estamos ainda ESTUDANDO e APLICANDO, dentro do possivel, os conceitos nele apresentados. Uma coisa é certa, como diz o professor MSc Robério (aqui da nossa região):
" A idéia pode até ser boa, mas quando se depara com a tecnologia nem tudo pode ser realizado e acaba muitas vezes voltando ao que existe no catalogo J2EE"

Ex.: Deixar o Repositorio similar a um DAO, senão igual

E quando lembro desse comentário e me deparo com um problema como esse, inclusive defendido pelo proprio Evans, quero entender como este cara pode ter pensado para resolver este tipo de problema… inclusive fugindo dos próprios princípios (pelo menos da forma como vejo agora)…

Assim, vou continuar estudando o Simples DDD.

Blz cabra, até a proxima!!

tnaires

AGAraujo:
Uma coisa é certa, como diz o professor MSc Robério (aqui da nossa região):
" A idéia pode até ser boa, mas quando se depara com a tecnologia nem tudo pode ser realizado (…)"

Até aqui posso concordar…

… mas aí já é chutar o pau da barraca! :lol:

sergiotaborda

Já que está estudando aproveite o seu tempo melhor. Estude Orientação a Objetos. Especialmente Analise e Modelagem Orientada a Objectos.
Depois leia o catalogo de padrões do Martin Fowler.
Só depois leia sobre DDD.

AGAraujo

sergiotaborda:
AGAraujo:

Voltando ao DDD, estamos ainda ESTUDANDO e APLICANDO, dentro do possivel, os conceitos nele apresentados. Uma coisa é certa, como diz o professor MSc Robério (aqui da nossa região):
" A idéia pode até ser boa, mas quando se depara com a tecnologia nem tudo pode ser realizado e acaba muitas vezes voltando ao que existe no catalogo J2EE"

Já que está estudando aproveite o seu tempo melhor. Estude Orientação a Objetos. Especialmente Analise e Modelagem Orientada a Objectos.
Depois leia o catalogo de padrões do Martin Fowler.
Só depois leia sobre DDD.

flw

Emerson_Macedo

http://www.objectmentor.com/resources/articles/dip.pdf

GutomCosta

Oi,

Mesmo o repositório sendo parte da camada de domínio, a implementação deste deve ficar na infrastructure, logo, a infra vai conhecer o domain.
Mas pensando bem, qual seria o lado negativo de fazer isso?
Se o grande benefício de DDD é o foco no domínio, isolar a domain layer parece ser mais importante.

Por outro lado, mesmo em implementações da Layered Architecture sem utilizar DDD, teríamos esta dependência, visto que de uma forma ou de outra, vamos ter que fazer o mapeamento objeto relacional. Acho que o grande problema aí fica por conta da Impedance Mismatch. Em algum lugar este mapeamento vai ter que ser feito.

No livro do evans mesmo, ele mostra o exemplo de um diagrama utilizando uma Factory que é responsável por fazer o mapeamento objeto relacional utilizando um ResultSet.

No livro do Jimmy Nilson, ele tem uma frase maneira: “Não lute com seu Framework”, acho que esta mensagem é interessante.

Valeu
Luiz Costa

tnaires

Essa mensagem tem no capítulo de repositórios do livro do Eric Evans, não lembro a página agora e nem tô com meu livro aqui pra conferir…

GutomCosta

Essa mensagem tem no capítulo de repositórios do livro do Eric Evans, não lembro a página agora e nem tô com meu livro aqui pra conferir…

É verdade, segue aqui o trecho:

Valeu
Luiz Costa

Criado 27 de novembro de 2009
Ultima resposta 16 de dez. de 2009
Respostas 29
Participantes 5