DEVBLUEPRINTS

Blog

  • Sobre o blog
  • Arquivo
  • Newsletter
  • RSS

Legal

  • Termos e Privacidade
  • Contato
  • Sobre mim

Inscreva-se na Newsletter

Autorizo o envio de comunicações por e-mail ou qualquer outro meio e concordo com os Termos e Política de Privacidade

 

Blog
  • Sobre o blog
  • Arquivo
  • Newsletter
  • RSS
Legal
  • Termos e Privacidade
  • Contato
  • Sobre mim
© 2026 Todos os direitos reservados — Desenhado e construido comFooter Heartpor Ednaldo Luiz
Blog/Back-end

Lei de Deméter: reduza acoplamento e pare o encadeamento

Chega de “train wreck”: aplique a Lei de Deméter para cortar acoplamento, simplificar testes e proteger seu domínio. Veja quando usar (e quando ignorar).

software design
java
object calisthenics
clean code
law of demeter
design principles
oop
Lei de Deméter: reduza acoplamento e pare o encadeamento
Ednaldo Luiz
Ednaldo Luiz
Nível: Intermediário
Nível:
Publicado: 06 de fevereiro de 2026
Última atualização: 06 de fevereiro de 2026

Nesta página

Compartilhe

Recomendados

Conteúdos relacionados a este artigo.

Ednaldo Luiz
GitHub
LinkedIn
Portfólio

Ednaldo Luiz

Arquiteto e Engenheiro de Software | Java & IA

Engenheiro de Software focado em arquitetura e performance. Trabalho com Java/Spring Boot, SQL bem estruturado, serviços escaláveis na AWS e soluções GenAI com RAG (LangChain + bases vetoriais). Valorizo código legível e decisões bem justificadas.
12 min de leitura
visualização: - visualização

Introdução

Se você já trombou com um código tipo a.getB().getC().fazAlgo() e sentiu aquela sensação de “isso vai dar ruim”, você não tá sendo dramático — na prática, é um detalhe interno do sistema vazando para quem usa.

um módulo não deve enxergar o interior dos objetos que ele manipula.

Fonte: Robert C. Martin, Clean Code, Cap. 6 (Objetos e Estruturas de Dados), seção "A lei de Demeter", p. 98.

A Lei de Deméter (o famoso Princípio do Menor Conhecimento) propõe uma regra direta: interaja apenas com seus “amigos imediatos”. Quando você fala com amigo de amigo, aumenta o acoplamento e torna o código mais frágil a mudanças internas.

Quanto mais você depende do trajeto interno A → B → C → D, mais frágil o sistema fica: muda um detalhe no meio e você quebra lugares que nem lembrava que existiam.

Essa ideia vem ficando mais clara pra mim conforme eu avanço na leitura do Clean Code (Robert C. Martin), especialmente no capítulo Objects and Data Structures — seção The Law of Demeter e no trecho Train Wrecks (páginas 97 a 99). É ali que você entende por que esse estilo de “navegação” espalha conhecimento demais e vira dívida técnica com juros.

Conexão rápida: Object Calisthenics

No Object Calisthenics, a 5ª regra é “One Dot Per Line” (um ponto por linha). Mas a moral não é contar ponto: é não fazer turismo dentro do objeto (Pedido → Cliente → Endereco → Cep).


O que é a Lei de Deméter

A Lei de Deméter diz: fale só com seus “amigos imediatos” — um objeto não deveria ficar “navegando” por dentro de outros objetos pra chegar onde quer.

Na prática, ela evita armadilhas como:

  • “navegar” por objetos (entrar, entrar de novo… até chegar no dado)
  • espalhar pelo sistema conhecimento sobre a estrutura interna do domínio
  • criar efeito dominó: uma refatoração no meio do caminho quebra trechos longe
  • transformar o domínio em getters + lógica espalhada (domínio anêmico: classes que só carregam dados, sem comportamento de negócio)

Amigos imediatos

A Lei de Deméter não é “proibido usar dois pontos na linha”. Isso é leitura literal e dá ruim.

Deméter é sobre limite de conhecimento: um método não deveria depender da estrutura interna de outro objeto.

Traduzindo: se, para fazer algo, você precisa navegar pela estrutura interna dos objetos (Pedido → Cliente → Endereco → Cep), está aumentando o acoplamento sem perceber.

Pensa em Deméter como uma pergunta de design: “Esse método deveria saber que esse caminho existe?”

Quem é amigo

Se quiser decidir rápido se algo é “amigo” ou “amigo do amigo”, usa essa tabela:

SituaçãoÉ amigo?ExemploPor quê
this✅this.validate()você mesmo
Campo direto✅this.clientevocê controla
Parâmetro recebido✅calcular(Pedido p)veio na assinatura
Objeto criado no método✅new Dinheiro(...)você criou, você manda
Dependência injetada✅gateway.cotar()colaborador explícito

Amigo imediato = this, campos diretos, parâmetro, objeto criado no método, dependência injetada.

Sinais de violação

Até código “bonitinho” pode esconder dependência do caminho.

1) Train wreck (o clássico)

Cadeias de chamadas como essa geralmente são consideradas descuidadas e devem ser evitadas.

Fonte: Robert C. Martin, Clean Code, Cap. 6, seção "Carrinhos de trem", p. 98-99.

O problema não é o ponto. É o serviço ficar dependente do caminho.

Funciona hoje. Amanhã alguém muda Endereco, troca o nome do campo ou a estrutura… e você quebra código longe.

Pensa num hotel: para conseguir uma toalha, você fala com a recepção — não com rouparia, corredor ou chaveiro. Se o hotel reorganizar tudo por dentro, seu pedido continua funcionando, porque o ponto de contato não mudou.

No código é a mesma coisa: quando você faz Pedido → Cliente → Endereco → Cep, você não usa o Pedido como contrato público — você depende do layout interno dele.

Se eu mudar Endereco, quantos arquivos eu quebro? Se a resposta for “um monte” ou “não sei”, já existe acoplamento espalhado.

2) “Quebrei em variáveis” (continua sendo chain)

Você acha que se livrou do problema só porque quebrou ele em 3 variáveis? Sinto muito, mas isso não resolveu nada. Só espalhou o acoplamento em 3 linhas. O trecho que pega o CEP ainda depende do caminho inteiro e o endereço continua sendo “amigo do amigo”.

3) Optional encadeado (o disfarce elegante)

Sintaticamente bonito. Mas na real? Continua sendo a mesma cadeia de dependência. O serviço de entrega ainda conhece o caminho inteiro até o CEP.

4) “Método repassador” (middle man)

Quando você aplica a Lei de Deméter, é comum pensar:
“vou criar um método no Pedido e pronto, acabou o train wreck”.

Isso não quebra Deméter. Cliente é amigo imediato do Pedido.
O risco é outro: se você repetir esse padrão pra tudo, sua classe vira uma secretária — cheia de atalhos que só repassam chamadas.

Errado (secretária: só cria túneis)

Você começa a entupir Pedido com “atalhos de navegação”:

A API cresce, a manutenção piora e você só mudou a chain de lugar.

Certo (método de intenção)

O mesmo repasse é bem-vindo quando tem intenção de domínio e protege o resto do sistema da estrutura interna dos objetos:

Regra prática (sem filosofar):
Se o método responde uma pergunta que faz sentido no domínio (“CEP de entrega”, “total do pedido”, “pode cancelar?”), ele é intenção.
Se ele existe só pra evitar getA().getB().getC(), ele é secretária.

Deméter não quer que você esconda pontos. Quer que você esconda dependência.

Sinais que costumam vir junto

Quando você vê um train wreck, quase sempre tem mais dois sinais andando colado com ele.

Feature Envy

Se um método vive cavando dados de outro objeto pra decidir, ele tá “morando no lugar errado”. Ele não usa o objeto — explora.

Aqui o problema não é o if, é o serviço saber demais sobre a estrutura interna de Cliente/Endereco.

Tell, Don’t Ask

Em vez de perguntar dados e decidir do lado de fora, empurre a decisão pro domínio (método de intenção).

devemos dizê-lo para fazer algo; não devemos perguntá-lo sobre sua estrutura interna.

Fonte: Robert C. Martin, Clean Code, Cap. 6, seção "Estruturas ocultas", p. 99.

Regra de review: se você pega dados pra decidir fora, talvez isso deva virar um método de intenção no domínio.


Exceções conscientes

Se isso é uma violação da Lei de Demeter depende se (...) são objetos ou estruturas de dados.

Fonte: Robert C. Martin, Clean Code, Cap. 6, seção "Carrinhos de trem", p. 99.

Deméter é mais importante onde existe comportamento e invariantes. Em dados puros, você pode ser mais relaxado, vamos ver alguns casos onde geralmente é aceitável navegar:

Value Objects / DTOs simples

Se Endereco for um VO de verdade (imutável, pequeno, estável e sem regra escondida), isso aqui pode ser ok:

A ideia aqui não é “liberar geral”. É só reconhecer que ler dado transparente é diferente de furar invariantes do domínio.

Biblioteca padrão / tipos estáveis

Encadeamentos em APIs estáveis e bem definidas geralmente não são o problema:

Aqui a cadeia não está expondo a estrutura interna do domínio; está só usando API pública consolidada.

API fluente intencional

Se o encadeamento existe porque a API foi desenhada pra isso, beleza:

Além de builders, isso também vale para query DSLs e pipelines que retornam o próprio tipo. O ponto é: isso não é “dependência do caminho”. É contrato público fluente.

Quando você ver uma chain, pergunta:

  • Isso é domínio comportamental (entidade/aggregate) ou dados (VO/DTO)?
  • O chamador deveria saber desse caminho?
  • Dá pra trocar “pegar dados e decidir fora” por método de intenção?
  • Se eu mudar Endereco, quantos arquivos quebram?

Exemplo completo

Vamos usar um caso realista: calcular frete. Pra isso, precisamos do CEP de entrega.

A ideia aqui é simples: primeiro você vai ver como o modelo é montado, depois o “train wreck” aparecendo naturalmente, e por fim a refatoração que corta o acoplamento.

Montando o modelo

Para explicar Deméter sem ruído, usei um recorte de domínio que aparece o tempo todo: pedido → cliente → endereço.

Esse é um caso comum em e-commerce, delivery, ERP e qualquer fluxo de entrega/cobrança.

A cadeia que a gente quer evitar:

Pedido → Cliente → Endereco → CEP

Endereco — o destino (onde mora o dado que a gente quer)

O Endereco é o “fim da linha”: ele guarda o CEP.

Quando esse detalhe muda (nome do campo, estrutura do endereço, validação), você não quer quebrar metade do sistema por causa de chamadas encadeadas.

Cliente — o elo do meio (onde o acoplamento começa a crescer)

O Cliente existe aqui pra representar o “passo intermediário” que costuma ser exposto via getter (getEndereco()), e é aí que a navegação começa a ficar tentadora.

Pedido — o ponto de entrada (o objeto que todo mundo tem na mão)

Em geral, regras de frete/checkout trabalham a partir de um Pedido.

Então quando alguém precisa do CEP, o caminho mais “fácil” vira: entrar no cliente, entrar no endereço… até achar o dado.

O problema

No ServicoDeEntrega, você só quer o CEP… mas acaba conhecendo o caminho inteiro:

O ServicoDeEntrega conhece Pedido — ok.

O que não é natural é ele saber que Pedido tem Cliente, que tem Endereco, que tem CEP.

A solução

Em vez do serviço navegar por dentro da estrutura interna de pedido, ele pede o que realmente precisa — uma chamada com intenção, não o caminho.

O ponto aqui é: o serviço só conversa com Pedido.

E aí vem a parte importante: Pedido expõe um método de intenção sem virar “depósito de chain”, ele delega para quem faz sentido.

Agora, pra isso não virar só “esconder a chain” dentro do Pedido, a delegação continua do jeito certo: o Pedido fala com Cliente, e o Cliente fala com Endereco.

Checkpoint: a Lei de Deméter reduz acoplamento porque o chamador para de depender da estrutura interna dos objetos.


Deméter nos testes

Se você já tentou escrever um teste unitário simples e acabou com uma árvore de mocks… isso quase nunca é “porque testar é chato”.

É porque seu código tá turistando por dentro dos objetos.

O problema: árvore de mocks

Se o serviço pega o CEP via pedido.getCliente().getEndereco().getCep(), o teste herda o mesmo caminho.

Resultado: você precisa mockar Pedido → Cliente → Endereco só pra chegar no dado.

Esse teste sofre com: acoplamento ao caminho, refatorações quebrando tudo e foco na estrutura (não na intenção).

Bordão aplicado em testes

Se eu mudar Endereco, quantos testes eu quebro?
Se a resposta for “um monte”, o problema não é o teste: é o acoplamento.

A solução: método de intenção

Na versão melhorada com Deméter (ServicoDeEntregaMelhor), o serviço conversa só com Pedido:

Ou seja: o caminho fica escondido atrás de um método de intenção.

E o teste fica mais simples:

Percebe a diferença? Você testa a intenção (“CEP de entrega”), não a estrutura.

Regra prática

  • Se, para testar um método, você precisa mockar 3+ objetos só para chegar num dado, é um sinal claro de violação da Lei de Deméter.
  • Se uma refatoração interna (ex.: mexer em Endereco) quebra testes “de regra”, seus testes estão acoplados ao caminho de acesso dos dados, não ao comportamento.
  • Prefira métodos de intenção que reduzam dependências em quem usa o código e nos testes.

Conclusão

Deméter não é sobre “quantos pontos tem na linha”. É sobre não depender da estrutura interna dos objetos.

Quando você precisa fazer Pedido → Cliente → Endereco → Cep, você não tá “usando o domínio”. Você tá furando o encapsulamento na marra e espalhando acoplamento onde ninguém vê — até o dia que uma refatoração vira efeito dominó.

  • Prefira método de intenção (pedido.getCepEntrega()), não “caminho”.
  • Se o teste exige árvore de mocks só pra pegar um dado, tem Deméter quebrado.
  • Se for domínio com invariantes, pega pesado.
  • Se for VO/DTO transparente ou API fluente intencional, relaxa — não vira fiscal de ponto.

Se seu código depende do trajeto, ele não é robusto — ele é refém da estrutura.


Getter + chamada no retorno
⚠️
pedido.getCliente().comprar()
“amigo do amigo”
Cadeia 2+ níveis🚨pedido.getCliente().getEndereco().getCep()dependência do caminho
Fluent API intencional✅consulta.onde().limitar()foi desenhado pra encadear
VO/DTO simples⚠️pessoa.getEndereco().getCidade()pode ser ok se for dado “transparente”
String cep = pedido.getCliente().getEndereco().getCep();
String cep = pedido.getCliente().getEndereco().getCep();
var cliente = pedido.getCliente();
var endereco = cliente.getEndereco();
var cep = endereco.getCep();
var cliente = pedido.getCliente();
var endereco = cliente.getEndereco();
var cep = endereco.getCep();
var cep = Optional.ofNullable(pedido.getCliente())
	.map(Cliente::getEndereco)
	.map(Endereco::getCep)
	.orElse(null);
var cep = Optional.ofNullable(pedido.getCliente())
	.map(Cliente::getEndereco)
	.map(Endereco::getCep)
	.orElse(null);
PedidoRepassador.java
package com.luizdev.articles.lawofdemeter;

public class PedidoRepassador {

	private final ClienteMelhor cliente;

	public PedidoRepassador(ClienteMelhor cliente) {
		this.cliente = cliente;
	}

	public String getCepEntrega() {
		return cliente.getCepEntrega(); // repassa
	}
}
PedidoRepassador.java
package com.luizdev.articles.lawofdemeter;

public class PedidoRepassador {

	private final ClienteMelhor cliente;

	public PedidoRepassador(ClienteMelhor cliente) {
		this.cliente = cliente;
	}

	public String getCepEntrega() {
		return cliente.getCepEntrega(); // repassa
	}
}
pedido.getRuaEntrega();
pedido.getCidadeEntrega();
pedido.getBairroEntrega();
pedido.getNumeroEntrega();
pedido.getRuaEntrega();
pedido.getCidadeEntrega();
pedido.getBairroEntrega();
pedido.getNumeroEntrega();
ServicoDeEntregaRepassador.java
package com.luizdev.articles.lawofdemeter;

public class ServicoDeEntregaRepassador {

	public String getCepEntrega(PedidoRepassador pedido) {
		return pedido.getCepEntrega(); // serviço só fala com Pedido
	}
}
ServicoDeEntregaRepassador.java
package com.luizdev.articles.lawofdemeter;

public class ServicoDeEntregaRepassador {

	public String getCepEntrega(PedidoRepassador pedido) {
		return pedido.getCepEntrega(); // serviço só fala com Pedido
	}
}
// o serviço tá com inveja do Cliente/Endereco
if (pedido.getCliente().getEndereco().getUf().equals("PE")) {
aplicarFreteEspecial();
}
// o serviço tá com inveja do Cliente/Endereco
if (pedido.getCliente().getEndereco().getUf().equals("PE")) {
aplicarFreteEspecial();
}
// em vez de perguntar UF pra decidir fora:
if (pedido.getCliente().getEndereco().getUf().equals("PE")) ...

// diga a intenção:
if (pedido.entregaEmPernambuco()) ...
// em vez de perguntar UF pra decidir fora:
if (pedido.getCliente().getEndereco().getUf().equals("PE")) ...

// diga a intenção:
if (pedido.entregaEmPernambuco()) ...
LeituraEmVO.java
var cidade = pessoa.getEndereco().getCidade();
LeituraEmVO.java
var cidade = pessoa.getEndereco().getCidade();
String nome = "  Ednaldo  ".trim().toLowerCase();
String nome = "  Ednaldo  ".trim().toLowerCase();
var nomes = lista.stream()
	.map(String::trim)
	.map(String::toLowerCase)
	.toList();
var nomes = lista.stream()
	.map(String::trim)
	.map(String::toLowerCase)
	.toList();
var request = HttpRequest.newBuilder()
	.uri(URI.create("https://api.exemplo.com/itens"))
	.timeout(Duration.ofSeconds(2))
	.header("Accept", "application/json")
	.GET()
	.build();
var request = HttpRequest.newBuilder()
	.uri(URI.create("https://api.exemplo.com/itens"))
	.timeout(Duration.ofSeconds(2))
	.header("Accept", "application/json")
	.GET()
	.build();
Endereco.java
package com.luizdev.articles.lawofdemeter;

public class Endereco {

	private final String cep;

	public Endereco(String cep) {
		this.cep = cep;
	}

	public String getCep() {
		return cep;
	}
}
Endereco.java
package com.luizdev.articles.lawofdemeter;

public class Endereco {

	private final String cep;

	public Endereco(String cep) {
		this.cep = cep;
	}

	public String getCep() {
		return cep;
	}
}
Cliente.java
package com.luizdev.articles.lawofdemeter;

import com.luizdev.articles.lawofdemeter.Endereco;

public class Cliente {

	private final Endereco endereco;

	public Cliente(Endereco endereco) {
		this.endereco = endereco;
	}

	public Endereco getEndereco() {
		return endereco;
	}
}
Cliente.java
package com.luizdev.articles.lawofdemeter;

import com.luizdev.articles.lawofdemeter.Endereco;

public class Cliente {

	private final Endereco endereco;

	public Cliente(Endereco endereco) {
		this.endereco = endereco;
	}

	public Endereco getEndereco() {
		return endereco;
	}
}
Pedido.java
package com.luizdev.articles.lawofdemeter;

import com.luizdev.articles.lawofdemeter.Cliente;

public class Pedido {

	private final Cliente cliente;

	public Pedido(Cliente cliente) {
		this.cliente = cliente;
	}

	public Cliente getCliente() {
		return cliente;
	}
}
Pedido.java
package com.luizdev.articles.lawofdemeter;

import com.luizdev.articles.lawofdemeter.Cliente;

public class Pedido {

	private final Cliente cliente;

	public Pedido(Cliente cliente) {
		this.cliente = cliente;
	}

	public Cliente getCliente() {
		return cliente;
	}
}
ServicoDeEntrega.java
package com.luizdev.articles.lawofdemeter;

import com.luizdev.articles.lawofdemeter.Pedido;

public class ServicoDeEntrega {

	public String getCepEntrega(Pedido pedido) {
		return pedido.getCliente().getEndereco().getCep();
	}
}
ServicoDeEntrega.java
package com.luizdev.articles.lawofdemeter;

import com.luizdev.articles.lawofdemeter.Pedido;

public class ServicoDeEntrega {

	public String getCepEntrega(Pedido pedido) {
		return pedido.getCliente().getEndereco().getCep();
	}
}
ServicoDeEntregaMelhor.java
package com.luizdev.articles.lawofdemeter;

import com.luizdev.articles.lawofdemeter.Pedido;

public class ServicoDeEntregaMelhor {

	public String getCepEntrega(Pedido pedido) {
		return pedido.getCepEntrega();
	}
}
ServicoDeEntregaMelhor.java
package com.luizdev.articles.lawofdemeter;

import com.luizdev.articles.lawofdemeter.Pedido;

public class ServicoDeEntregaMelhor {

	public String getCepEntrega(Pedido pedido) {
		return pedido.getCepEntrega();
	}
}
PedidoMelhor.java
package com.luizdev.articles.lawofdemeter;

public class PedidoMelhor {

	private final ClienteMelhor cliente;

	public PedidoMelhor(ClienteMelhor cliente) {
		this.cliente = cliente;
	}

	public String getCepEntrega() {
		return cliente.getCepEntrega();
	}
}
PedidoMelhor.java
package com.luizdev.articles.lawofdemeter;

public class PedidoMelhor {

	private final ClienteMelhor cliente;

	public PedidoMelhor(ClienteMelhor cliente) {
		this.cliente = cliente;
	}

	public String getCepEntrega() {
		return cliente.getCepEntrega();
	}
}
ClienteMelhor.java
package com.luizdev.articles.lawofdemeter;

public class ClienteMelhor {

	private final Endereco endereco;

	public ClienteMelhor(Endereco endereco) {
		this.endereco = endereco;
	}

	public Endereco getEndereco() {
		return endereco;
	}

	public String getCepEntrega() {
		return endereco.getCep();
	}
}
ClienteMelhor.java
package com.luizdev.articles.lawofdemeter;

public class ClienteMelhor {

	private final Endereco endereco;

	public ClienteMelhor(Endereco endereco) {
		this.endereco = endereco;
	}

	public Endereco getEndereco() {
		return endereco;
	}

	public String getCepEntrega() {
		return endereco.getCep();
	}
}
TesteServicoDeEntrega.java
package com.luizdev.articles.lawofdemeter;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;

public class TesteServicoDeEntrega {

	@Test
	void deve_obter_cep_para_calcular_frete() {
		Pedido pedido = mock(Pedido.class);
		Cliente cliente = mock(Cliente.class);
		Endereco endereco = mock(Endereco.class);

		when(pedido.getCliente()).thenReturn(cliente);
		when(cliente.getEndereco()).thenReturn(endereco);
		when(endereco.getCep()).thenReturn("50000-000");

		ServicoDeEntrega servico = new ServicoDeEntrega();
		String cep = servico.getCepEntrega(pedido);

		assertEquals("50000-000", cep);
	}
}
TesteServicoDeEntrega.java
package com.luizdev.articles.lawofdemeter;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;

public class TesteServicoDeEntrega {

	@Test
	void deve_obter_cep_para_calcular_frete() {
		Pedido pedido = mock(Pedido.class);
		Cliente cliente = mock(Cliente.class);
		Endereco endereco = mock(Endereco.class);

		when(pedido.getCliente()).thenReturn(cliente);
		when(cliente.getEndereco()).thenReturn(endereco);
		when(endereco.getCep()).thenReturn("50000-000");

		ServicoDeEntrega servico = new ServicoDeEntrega();
		String cep = servico.getCepEntrega(pedido);

		assertEquals("50000-000", cep);
	}
}
return pedido.getCepEntrega();
return pedido.getCepEntrega();
TesteServicoDeEntregaMelhor.java
package com.luizdev.articles.lawofdemeter;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;

public class TesteServicoDeEntregaMelhor {

	@Test
	void deve_obter_cep_para_calcular_frete() {
		Pedido pedido = mock(Pedido.class);
		when(pedido.getCepEntrega()).thenReturn("50000-000");

		ServicoDeEntregaMelhor servico = new ServicoDeEntregaMelhor();
		String cep = servico.getCepEntrega(pedido);

		assertEquals("50000-000", cep);
	}
}
TesteServicoDeEntregaMelhor.java
package com.luizdev.articles.lawofdemeter;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.Test;

public class TesteServicoDeEntregaMelhor {

	@Test
	void deve_obter_cep_para_calcular_frete() {
		Pedido pedido = mock(Pedido.class);
		when(pedido.getCepEntrega()).thenReturn("50000-000");

		ServicoDeEntregaMelhor servico = new ServicoDeEntregaMelhor();
		String cep = servico.getCepEntrega(pedido);

		assertEquals("50000-000", cep);
	}
}
Questão1/5

Qual é a ideia central da Lei de Deméter?

ABC
A depende de B para alcançar C: o chamador atravessa objetos internos para chegar no que quer.
ABCOKNão recomendadoA é um"amigo" de BB é um"amigo" de CUm amigo de umamigo é umdesconhecido
ServiçoPedidoClienteEndereço
Serviço fala com Pedido; Pedido fala com Cliente; Cliente fala com Endereco. Sem dependência do caminho interno.