Questão de Programação — Linguagens de programação — FGV 2024
Programação›Linguagens 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:Este código viola o Princípio da Inversão de Dependência (DIP). Para seguir corretamente o DIP, deve-se refatorar o código
Aremovendo a dependência de ServicoDePagamento e movendo a lógica de pagamento diretamente para a classe Pedido.
Busando um padrão Singleton para ServicoDePagamento e ServicoDeNotificacao, garantindo que as instâncias sejam compartilhadas entre diferentes classes.
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
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.
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
Pedido → ServicoDePagamento (concreto)
Pedido → IPagamento (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.
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 Pedidoaumenta 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.