Boas práticas e padrões · Princípios SOLID · 6 min de leitura
D — Princípio da inversão de dependência (DIP)
Regras de negócio não dependem de detalhes (banco, HTTP, SDK): os dois dependem de abstrações definidas pelo negócio.
Arraste para o lado para ver o diagrama inteiro.
As duas regras
- Módulos de alto nível não dependem de módulos de baixo nível; ambos dependem de abstrações.
- Abstrações não dependem de detalhes; detalhes dependem de abstrações.
A "inversão" é que a interface pertence a quem usa (o domínio), não a quem implementa (a infraestrutura).
DIP não é DI
Injeção de dependência é a técnica de entregar as dependências por construtor (ou contêiner). Inversão de dependência é a direção das setas entre módulos. A injeção é o jeito mais comum de aplicar a inversão.
Ganho concreto
Trocar Postgres por Room, Retrofit por Ktor ou rodar o caso de uso inteiro em teste unitário com um repositório em memória — sem mocks complexos.
No código: antes e depois
class CadastrarCliente {
private val db = PostgresClient("jdbc:postgresql://prod/db") // detalhe dentro da regra
fun executar(c: Cliente) {
require(c.email.contains("@"))
db.insert("clientes", c)
}
} // domínio
interface ClienteRepository { suspend fun salvar(c: Cliente) }
class CadastrarCliente(private val repo: ClienteRepository) {
suspend fun executar(c: Cliente) {
require(c.email.contains("@")) { "e-mail inválido" }
repo.salvar(c)
}
}
// infraestrutura
class PostgresClienteRepository(private val db: PostgresClient) : ClienteRepository {
override suspend fun salvar(c: Cliente) = db.insert("clientes", c)
}
// teste
class FakeRepo : ClienteRepository {
val salvos = mutableListOf<Cliente>()
override suspend fun salvar(c: Cliente) { salvos += c }
} O caso de uso não sabe que Postgres existe. Em teste, FakeRepo verifica o comportamento em milissegundos.
Em resumo
- A interface mora no domínio, perto de quem usa.
- Infraestrutura implementa as interfaces do domínio.
- DIP é a direção; DI é a técnica de montagem.
- Testes rápidos com fakes em memória.