Sobes.tech
Middle

Qual é a diferença entre inversão de controlo (IoC) e injeção de dependências?

sobes.tech IA

Resposta da IA

A inversão de controlo (IoC) é um princípio geral de conceção segundo o qual o fluxo de controlo de um programa muda: em vez de gerir explicitamente as dependências e a lógica da sua chamada, o componente confia num framework externo ou contêiner que gere esse fluxo.

A injeção de dependências (DI) é um dos padrões específicos que implementam o princípio IoC. Consiste em passar as dependências (objetos dos quais depende o componente atual) ao componente de fora, em vez de o componente os criar ou procurar por si próprio.

Assim, a DI é uma forma de alcançar a IoC.

As principais diferenças:

  • IoC — princípio/conceito.
  • DI — padrão/implementação.
  • A IoC pode ser implementada de várias formas (por exemplo, método de fábrica, localizador de serviços), a DI é uma dessas formas.
  • A IoC transfere a responsabilidade de criar e ligar objetos de o componente para o framework ou contêiner.
  • A DI realiza essa transferência, passando as dependências através do construtor, setter ou interface.

Exemplo de DI (construtor):

// classe dependente de Service
public class Client {
    private final Service service;

    // O construtor recebe a dependência (Service)
    public Client(Service service) {
        this.service = service;
    }

    public void doSomething() {
        service.execute();
    }
}

// Interface de dependência
public interface Service {
    void execute();
}

// Implementação concreta de dependência
public class ServiceImpl implements Service {
    @Override
    public void execute() {
        System.out.println("A executar serviço...");
    }
}

// Classe responsável pela "injeção"
public class AppConfig {
    public static void main(String[] args) {
        Service myService = new ServiceImpl(); // Criação da dependência
        Client client = new Client(myService); // Injeção de dependência através do construtor
        client.doSomething();
    }
}

Neste exemplo, a classe Client não cria ServiceImpl diretamente. Em vez disso, ServiceImpl é criado noutro lugar (AppConfig) e passado (inyectado) ao Client através do seu construtor. Isto implementa o princípio IoC, uma vez que a gestão da criação e ligação de Service está invertida — não está no Client.