JPQL, encapsulamento, acoplamento e Law of Demeter

Há pouco tempo venho usando java e seus frameworks, por isso essa necessidade recorrente da ajuda de vocês.

Tenhu usado JPQL e me ocorreu que esta fere The Law of Demeter quando se escreve:


SELECT o FROM Classe o WHERE o.atributo1.atributo2.atributo3.etc == "teste"

Já no o.ATRIBUTO1 JPQL fura o encapsulamento da classe, aumentando assim o acoplamento das consultas JPQL com a estrutura interna da classe, ou seja, se a estrutura interna da classe for alterada todas as consultas acopladas a esta também terão de ser alteradas! Que mer#%%$!

Existe alguma formar de desacoplar as consultas da estrutura interna da classe?

Tem que funcionar no mínimo em casos como este:


Class Cep {
     private String cep;
     ...
}

Class Endereco {
     ...
     private Cep cep;
     ...
}

Class Consumidor {
     ...
     private Endereco endereco;
     ...
}

A consulta seria: Consultar todos os Consumidores que residam em um determinado CEP.

SELECT c FROM Consumidor c WHERE c.endereco.cep == ?

Como seria esta consulta de forma desacoplada?

[]s

Conto com a ajuda de vocês!

Uma questão muito bem levantada…

Bom, não sou um grande especialista mas vou dar um pitaco. O negócio é que frameworks ORM têm algumas características um pouco incômodas quando se pensa por um ponto de vista mais teórico. Por exemplo, o Model ser “invadido” por anotações do framework, e esse fato que vc acabou de citar.

Creio que isso aconteça porque o ORM consegue isolar um pouco o “mundo dos objetos” do “mundo relacional”, mas não isola totalmente. No fundo eles sempre serão relacionais, e sempre o “Cliente terá Endereço que terá CEP”. E aí não faz sentido pensar em acoplamento e lei de Demeter porque esses conceitos se aplicam mais a objetos mesmo.

Esse é o motivo do “acoplamento”, é um espelho do relacionamento no BD. Agora se a ferramenta permite contornar o problema eu não sei, não tenho tanta experiência com frameworks ORM.

Ninguém mais para opinar?

Também queria ver algumas opiniões mais embasadas.

[size=7]brunohansen, me desculpe, contaminei seu tópico com a Maldição do Forever Alone… é que toda vez que eu respondo uma thread ela morre rsrs[/size]

seria interessante se alguém conhecer uma forma de desacoplar isso… mas aparentemente acho que não tem muito jeito, a parte mais alta conhece as mais baixas, nesse exemplo o Consumidor conhece Endereço que por sua vez conhece cep, mesmo que cep não conheça endereço que por sua vez não conheça consumidor… da mesma forma que um view conhece o controller e o controller conheça o modelo (mesmo com coisas como injeção de dependencia por exemplo, um controller pode até não ter criado/instanciado um modelo mas ainda precisa saber o que invocar dentro do modelo em questão)… mesmo que o modelo não conheça o controller e possa ser portado para outro controller…

bom, eu posso estar sendo meio leigo, mas nunca vi uma solução onde as camadas mais altas não precisem conhecer as mais baixas…

creio que é mais comum ver a aplicação da LOD nas classes que ligam as camadas da app.

ex: controller -> service -> repository -> entityManager …

se for fazer isso nas classes de entidade, na minha opinião, pode deixar o sistema com uma complexidade desnecessária…

att.,