Pular para o conteúdo principal

Questão de Programação — Linguagens de programação — FGV 2024

ProgramaçãoLinguagens de programação
Código
fg079643
Banca
FGV
Órgão
DATAPREV
Ano
2024
Nível
Superior
Cargo
ATI - Arquitetura, Engenharia e Sustentação Tecnológica
Uma aplicação de e-commerce possui a seguinte classe Pedido, que cria diretamente uma instância de ServicoDePagamento e ServicoDeNotificacao para processar pagamentos e enviar notificações ao cliente:Q51.png 377×170Este código viola o Princípio da Inversão de Dependência (DIP). Para seguir corretamente o DIP, deve-se refatorar o código
  1. Aremovendo a dependência de ServicoDePagamento e movendo a lógica de pagamento diretamente para a classe Pedido.
  2. Busando um padrão Singleton para ServicoDePagamento e ServicoDeNotificacao, garantindo que as instâncias sejam compartilhadas entre diferentes classes.
  3. Cintroduzindo interfaces IPagamento e INotificacao, e injetando-as via construtor na classe Pedido, permitindo a inversão de dependências para abstrações em vez de implementações concretas
  4. Dalterando o código para usar herança, fazendo com que Pedido herde de uma classe abstrata que define os métodos de pagamento e notificação.
  5. Ecriando uma fábrica (Factory) que cria instâncias de ServicoDePagamento e ServicoDeNotificacao e as injeta na classe Pedido.
Revelar gabarito e comentário

GabaritoC — introduzindo interfaces IPagamento e INotificacao, e injetando-as via construtor na classe Pedido, permitindo a inversão de dependências para abstrações em vez de implementações concretas

Comentário gerado por IA. É um apoio ao estudo, ancorado em fontes, mas pode conter imprecisões — confira sempre na fonte oficial (lei, súmula, edital e gabarito da banca). Encontrou um erro? Use “Reportar”.

Princípio da Inversão de Dependência (DIP) e Injeção de Dependência

Gabarito: letra C. O código viola o DIP porque a classe Pedido depende diretamente de implementações concretas (ServicoDePagamento e ServicoDeNotificacao), criando-as internamente. A refatoração correta é introduzir abstrações (interfaces IPagamento e INotificacao) e injetá-las via construtor, invertendo a dependência para abstrações em vez de implementações concretas — exatamente o que a alternativa C descreve.

O Princípio da Inversão de Dependência (DIP) é o "D" do acrônimo SOLID, um dos cinco princípios de design orientado a objetos. Ele estabelece duas regras fundamentais: (1) módulos de alto nível não devem depender de módulos de baixo nível; ambos devem depender de abstrações; e (2) abstrações não devem depender de detalhes; detalhes devem depender de abstrações. Em termos práticos, isso significa que uma classe que orquestra o fluxo de negócio (como Pedido) não deveria instanciar diretamente suas dependências concretas (como ServicoDePagamento), pois isso cria um acoplamento rígido: qualquer mudança na implementação concreta força alteração na classe de alto nível, e testar a classe isoladamente se torna difícil.

A violação no código do enunciado é clássica: Pedido cria diretamente new ServicoDePagamento() e new ServicoDeNotificacao() dentro de seus métodos ou construtor. Isso fere o DIP porque a classe de alto nível (Pedido) depende de classes concretas de baixo nível, em vez de depender de abstrações. A solução canônica é aplicar a Injeção de Dependência (DI): definir interfaces que representem os contratos (IPagamento, INotificacao), e receber as implementações prontas via construtor (ou setter, ou fábrica), em vez de criá-las internamente. Assim, Pedido passa a depender apenas das abstrações, e as implementações concretas podem ser trocadas, mockadas em testes e configuradas externamente sem alterar a classe de alto nível.

Para fixar, veja a diferença entre o código violador e o refatorado:

Aspecto

Código violador (antes)

Código refatorado (depois)

Dependência

PedidoServicoDePagamento (concreto)

PedidoIPagamento (abstração)

Criação

new ServicoDePagamento() dentro de Pedido

Injeção via construtor

Acoplamento

Alto (rígido)

Baixo (flexível)

Testabilidade

Difícil (não dá para mockar)

Fácil (injetar mock)

A pegadinha da banca está em confundir DIP com outros padrões e princípios: Singleton (alternativa B) resolve instância única, não inversão de dependência; herança (alternativa D) cria acoplamento por herança, não por composição; Factory (alternativa E) até ajuda a desacoplar a criação, mas não é a essência do DIP — o núcleo é depender de abstrações, e a injeção via construtor é a forma mais direta de alcançar isso. Guarde a fronteira: DIP = depender de abstrações; DI = fornecer as dependências de fora; Factory = centralizar a criação. É exatamente nessa distinção que as alternativas se dividem.

1Regras
Alto nível não depende de baixo nível
Ambos dependem de abstrações
2Violação
Classe cria dependência concreta
Acoplamento rígido
3Correção
Introduzir interfaces
Injetar via construtor
4Confusões comuns
Singleton (instância única)
Factory (centraliza criação)
Herança (acoplamento forte)
DIP (SOLID)
LEVELsoulevel.com.br
DIP (SOLID): Regras (Alto nível não depende de baixo nível, Ambos dependem de abstrações); Violação (Classe cria dependência concreta, Acoplamento rígido); Correção (Introduzir interfaces, Injetar via construtor); Confusões comuns (Singleton (instância única), Factory (centraliza criação), Herança (acoplamento forte))

Alternativa A — ❌ Incorreta

Remover a dependência de ServicoDePagamento e mover a lógica de pagamento diretamente para Pedido aumenta o acoplamento e viola ainda mais o DIP, além de violar o Princípio da Responsabilidade Única (SRP), pois Pedido passaria a acumular responsabilidades de negócio e de pagamento. O DIP não pede para eliminar dependências, mas para invertê-las: depender de abstrações, não de implementações.

Alternativa B — ❌ Incorreta

O padrão Singleton garante uma única instância global de ServicoDePagamento e ServicoDeNotificacao, mas não resolve a inversão de dependência. Pedido continuaria dependendo das classes concretas (via getInstance()), apenas com uma instância compartilhada. O DIP exige abstração, não controle de instanciação. Além disso, Singleton é frequentemente criticado por dificultar testes, justamente o oposto do que o DIP busca.

Alternativa C — ✅ Correta ⟵ GABARITO

Esta é a refatoração canônica do DIP: introduzir interfaces IPagamento e INotificacao (abstrações) e injetá-las via construtor na classe Pedido. Com isso, Pedido passa a depender apenas das abstrações, e as implementações concretas (ServicoDePagamento, ServicoDeNotificacao) podem ser fornecidas externamente — seja em produção, seja em testes com mocks. Isso atende literalmente às duas regras do DIP: módulos de alto nível dependem de abstrações, e detalhes dependem de abstrações.

Alternativa D — ❌ Incorreta

Usar herança, fazendo Pedido herdar de uma classe abstrata com métodos de pagamento e notificação, viola o princípio de composição sobre herança e não resolve o DIP. Herança cria um acoplamento forte entre a superclasse e a subclasse, e Pedido continuaria dependendo de uma implementação concreta (a classe abstrata). O DIP favorece composição (injeção de dependências) em vez de herança para desacoplar.

Alternativa E — ❌ Incorreta

Uma Factory que cria as instâncias e as injeta em Pedido é uma boa prática e pode ser combinada com o DIP, mas a alternativa está incompleta e não é a essência do princípio. O núcleo do DIP é depender de abstrações (interfaces), não apenas centralizar a criação. Se a Factory injetar as implementações concretas diretamente, sem interfaces, o DIP continua violado. A alternativa C é mais completa e direta: introduz as abstrações e injeta via construtor.

NÃO CAIA NESSA!

A banca explora a confusão entre DIP e outros padrões. A alternativa E (Factory) parece razoável, mas o DIP não é sobre como criar as dependências — é sobre de que depender: abstrações, não implementações. A alternativa B (Singleton) também parece plausível, mas resolve instância única, não inversão de dependência. A pegadinha clássica é trocar o "D" do SOLID por um padrão de criação. Com treino, você enxerga essas trocas de longe 💪

PEGA ESSA DICA!

Para questões de SOLID, decore o acrônimo e o que cada letra ataca: SRP (uma classe, uma responsabilidade), OCP (aberto para extensão, fechado para modificação), LSP (subtipos substituíveis), ISP (interfaces segregadas), DIP (depender de abstrações). Quando a questão descrever uma classe que instancia outras diretamente, o DIP é o princípio violado — a correção quase sempre envolve interfaces + injeção via construtor.

Gabarito: letra C

Link permanente: /questoes/fg079643