Formalmente falando, um método M de um objeto O só pode consumir serviços dos seguintes tipos de objetos:
- Do próprio objeto O;
- Parâmetros de M;
- Qualquer objeto criado/instanciado por M;
- Componentes diretos de O.
A grande maioria do material sobre a lei na Internet, usa o exemplo do cachorro:
Quando você precisa que um cachorro ande, você dá a ordem para as pernas diretamente, ou para o cachorro? Obviamente que para o cachorro e este sabe o que precisa ser acionado para andar.
Vamos demonstrar essa teoria:
package br.com.celsomartins.cachorro;
import java.util.ArrayList;
import java.util.List;
public class Cachorro {
private List <Pata> patas = new ArrayList <Pata>();
public boolean andar() {
for (Pata pata: patas) {
if (!pata.andar()) {
return false;
}
}
return true;
}
}
package br.com.celsomartins.cachorro;
public class Pata {
public boolean andar() {
return true;
}
}
O que a Lei de Deméter diz é para não enviarmos mensagens para Pata e sim para Cachorro, que fará a delegação para as patas e estas para as classes que forem necessárias para fazer o cachorro andar.
A diferença é clara:
disso:
...
for (Pata pata: cachorro.getPatas()){
pata.andar();
}
para isso:
cachorro.andar();
Dá para notar a facilidade de manutenção nesse exemplo? Posso alterar o comportamento das patas e o cão continua andando, sem afetar o cliente da classe
Cachorro
. O cachorro pode ter perdido uma das patas e andar com apenas três, isso não é importante para o cliente da classe. A complexidade da ação está encapsulada. Não é preciso ninguém saber quais músculos, ossos, tendões, etc estão envolvidos na ação. Isso não é problema de quem está dando a ordem para o cão. Com a complexidade encapsulada, reduzimos dependências desnecessárias, facilitando a manutenção, aumentando a flexibilidade do nosso sistema.
Outro exemplo prático podemos encontrar nesse artigo.
Até a próxima.
Parte I - Introdução
Parte II - Correção
Parte III - Design por contrato
Parte IV - Flexibilidade
Parte VI - Eficiência
Parte VII - Coesão
Parte VIII - Usabilidade
Parte IX - Relacionamento entre classes
Gostei demais dos artigos de Pincipios de Projetos, parabéns, muito bom mesmo.
ResponderExcluirGostei também do Widget do evento, vai no Falando em Java?
[]sss
Muito obrigado!!
ResponderExcluirVou sim. A previsão da minha chegada a SP é 6hs. Vou sair do RJ as 0hs. Nos encontramos lá.
Abraços!
ótimo post. realmente a qualidade do blog é indiscutivel.
ResponderExcluirOutro beneficio da lei de demeter é evitar a navegação transitiva. ex:
obj1.getObj2().getObj4().fazAlgo();
além de criar um codigo longo o cliente deste codigo fica conhecendo mais objetos do que deveria, causando alto acoplamento.
Imagine que houve uma mudança no modelo e agora quem contem o obj4 é o obj3. Seria necessaria uma busca por todas as ocorrencias do codigo acima para adicionar o obj3 as chamadas:
obj1.getObj2().getOjb3().getObj4().fazAlgo();
O correto seria:
obj1.fazAlgo() e dentro deste metodo ele faz as chamadas aos demais objetos.
grande abrasss e sucesso!!!
Oi @Renan.
ResponderExcluirObrigado pelo elogio e pela participação.
Você tem razão. Muito bom o seu comentário.
Abraços