Skip to content

ezequielweb/java-solid--dependency-inversion-principle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SOLID - Dependency Inversion Principle (DIP)

📚 O que é o Dependency Inversion Principle?

O Dependency Inversion Principle (Princípio da Inversão de Dependência) é o "D" do SOLID e afirma que:

"Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações."

"Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações."

Por que é importante?

  • Desacoplamento: Reduz a dependência entre módulos
  • Flexibilidade: Facilita a troca de implementações
  • Testabilidade: Permite usar mocks e stubs em testes
  • Manutenibilidade: Mudanças em detalhes não afetam módulos de alto nível

🎯 O Desafio

Você tem um Sistema de Notificações que viola o DIP. Seu objetivo é refatorá-lo para seguir o princípio corretamente.

❌ Problema na versão errada (Wrong)

A classe NotificationService (alto nível) depende diretamente das classes concretas:

  • EmailService (baixo nível)
  • SMSService (baixo nível)
  • PushNotificationService (baixo nível)

Consequências:

  • Difícil adicionar novos tipos de notificação
  • Difícil testar sem enviar notificações reais
  • Alto acoplamento entre as classes
  • Violação do Open/Closed Principle também

✅ Solução esperada

  1. Criar uma abstração (interface) INotificationSender
  2. Fazer as classes de baixo nível implementarem a interface:
    • EmailService implements INotificationSender
    • SMSService implements INotificationSender
    • PushNotificationService implements INotificationSender
  3. Fazer a classe de alto nível depender da abstração:
    • NotificationService deve receber INotificationSender (não classes concretas)

🚀 Como resolver

Passo 1: Entenda o problema

# Execute a versão errada para ver como funciona
./gradlew run

Passo 2: Implemente a solução

Na pasta Solution, crie as seguintes classes:

  1. INotificationSender.java - Interface que define o contrato de envio
  2. EmailService.java - Implementação que envia por email
  3. SMSService.java - Implementação que envia por SMS
  4. PushNotificationService.java - Implementação que envia push notifications
  5. NotificationService.java - Classe de alto nível que depende da interface (não das implementações!)
  6. SolutionVersion.java - Classe para demonstrar o uso da solução

Lembre-se: A classe NotificationService deve receber a dependência via construtor (Dependency Injection)!

Passo 3: Teste sua solução

  1. Abra o arquivo App.java
  2. Comente a linha que chama WrongVersion.run()
  3. Descomente a linha que chama SolutionVersion.run()
  4. Execute novamente:
    ./gradlew run

🎓 Conceitos importantes

Inversão de Dependência vs Injeção de Dependência

  • Inversão de Dependência (DIP): Princípio de design que diz para depender de abstrações
  • Injeção de Dependência (DI): Padrão/técnica para implementar o DIP (passar dependências via construtor, setter, etc.)

Alto Nível vs Baixo Nível

  • Alto Nível: Contém lógica de negócio, regras, políticas (ex: NotificationService)
  • Baixo Nível: Implementa detalhes técnicos, I/O, infraestrutura (ex: EmailService, SMSService)

✨ Benefícios da sua solução

Após implementar corretamente, você terá:

  • Fácil extensão: Adicionar WhatsAppService sem modificar NotificationService
  • Testável: Pode criar um MockNotificationSender para testes
  • Desacoplado: NotificationService não conhece detalhes de implementação
  • Flexível: Pode trocar implementações em tempo de execução

🤔 Dicas

  1. A interface deve estar no mesmo nível conceitual da classe de alto nível
  2. Use injeção de dependência via construtor para passar a implementação
  3. Pense em como facilitar testes ao resolver o problema
  4. A classe de alto nível não deve criar instâncias das classes de baixo nível

📖 Referências


Boa sorte! 🚀

About

Desafio técnico da aplicação do D do SOLID.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages