Dependencia entre as camadas

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.

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.

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.

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

[quote=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?[/quote]
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.

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

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.

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.

[quote=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?[/quote]
    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.

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

Valeu pela explicação!

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.

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

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.

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.[/quote]

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)

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.

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.[/quote]

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?

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 )

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 )[/quote]

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…

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ê…

[quote=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 )[/quote]
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.

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ê…[/quote]

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.

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: