Na programação, objetos precisam "conversar" para realizar tarefas. A Lei de Demeter é uma regra simples que organiza esse diálogo: fale apenas com seus amigos imediatos. Seguir essa lei nos ajuda a escrever um código mais limpo, desacoplado e muito mais fácil de dar manutenção no futuro.
Explicação
Pense que você quer que seu cachorro se mova. Você não comanda as patas dele individualmente; você simplesmente diz "ande!" ao cachorro. O cachorro (seu amigo imediato) é quem sabe como mover as próprias patas.
No código, isso significa que um método só deve chamar métodos de objetos com os quais ele tem uma relação direta: seus próprios atributos, objetos recebidos como parâmetro ou objetos que ele mesmo criou. Ele não deve pedir um objeto para, então, pedir outro objeto a ele, e assim por diante.
Exemplo Prático
Vamos ver um código que quebra a regra e como consertá-lo. O objetivo é pegar o CEP do endereço de um estudante.
Classes:
class Endereco {
public String getCep() { return "12345-678"; }
}
class Estudante {
private Endereco endereco = new Endereco();
public Endereco getEndereco() { return endereco; }
}
class Escola {
private Estudante estudante = new Estudante();
public Estudante getEstudante() { return estudante; }
}
1. Violação da Lei (o jeito errado)
Essa cadeia de chamadas (get().get().get()
) é um sinal de alerta. A classe
SistemaDeMatricula
sabe demais sobre a
estrutura interna da Escola
e do Estudante
.
public class SistemaDeMatricula {
public void imprimirCep(Escola escola) {
// ERRADO: estamos "falando com um estranho" (o Endereco)
String cep = escola.getEstudante().getEndereco().getCep();
System.out.println("CEP: " + cep);
}
}
2. Seguindo a Lei (o jeito certo)
Refatoramos o código para que cada classe delegue a tarefa ao seu "amigo imediato".
Primeiro, a classe principal (SistemaDeMatricula
) apenas pede o que quer para a Escola
:
// Certo: Apenas falamos com nosso amigo direto, a escola.
public void imprimirCep(Escola escola) {
String cep = escola.getCepDoEstudante();
System.out.println("CEP: " + cep);
}
Para isso funcionar, criamos métodos que delegam a chamada em cada classe:
// Na classe Escola, delegamos para Estudante
class Escola {
private Estudante estudante = new Estudante();
public String getCepDoEstudante() {
return estudante.getCep(); // Pede o CEP ao seu amigo "estudante"
}
}
// Na classe Estudante, delegamos para Endereco
class Estudante {
private Endereco endereco = new Endereco();
public String getCep() {
return endereco.getCep(); // Pede o CEP ao seu amigo "endereco"
}
}
Agora, se a estrutura interna de Estudante
mudar, a classe SistemaDeMatricula
não será
afetada.
Conclusão
A Lei de Demeter nos incentiva a escrever um código menos "bisbilhoteiro". Ao fazer isso, reduzimos o acoplamento
entre as classes, o que torna o sistema mais flexível e fácil de manter. Se você vir uma longa cadeia de .get()
,
lembre-se: é um bom momento para refatorar e delegar!