Aula 139: Injeção de Dependência em Swift
A Injeção de Dependência (DI) é um padrão de design que permite que uma classe receba suas dependências de fontes externas, em vez de criá-las internamente. Isso resulta em um código mais modular, testável e fácil de manter. Nesta aula, vamos explorar os diferentes tipos de injeção de dependência em Swift e fornecer exemplos para ilustrar como implementá-los de forma eficaz.
O que é Injeção de Dependência?
De forma simples, Injeção de Dependência é uma técnica onde um objeto (o dependente) recebe suas dependências (os serviços ou recursos de que precisa) em vez de criar essas dependências por conta própria. Essa separação de responsabilidades promove o desacoplamento em sua aplicação, facilitando a gestão e os testes.
Tipos de Injeção de Dependência
Existem três tipos principais de injeção de dependência:
- Injeção pelo Construtor: As dependências são fornecidas através do construtor da classe.
- Injeção por Propriedades: As dependências são fornecidas através de propriedades públicas.
- Injeção por Métodos: As dependências são fornecidas através de parâmetros de métodos.
Injeção pelo Construtor
A injeção pelo construtor é o método mais comumente utilizado. Você define uma classe que aceita suas dependências como parâmetros no inicializador.
class ServicoBanco {
func buscarDados() -> String {
return "Dados do banco de dados"
}
}
class ServicoUsuario {
private let servicoBanco: ServicoBanco
init(servicoBanco: ServicoBanco) {
self.servicoBanco = servicoBanco
}
func obterDadosUsuario() -> String {
return servicoBanco.buscarDados()
}
}
// Uso
let servicoBanco = ServicoBanco()
let servicoUsuario = ServicoUsuario(servicoBanco: servicoBanco)
print(servicoUsuario.obterDadosUsuario()) // Saída: Dados do banco de dados
Injeção por Propriedades
Às vezes, você pode querer injetar dependências após a instância ter sido criada. Isso pode ser feito através de propriedades.
class ServicoLogger {
func log(mensagem: String) {
print("Log: \(mensagem)")
}
}
class ServicoPedido {
var servicoLogger: ServicoLogger?
func criarPedido() {
servicoLogger?.log(mensagem: "Pedido criado")
}
}
// Uso
let servicoPedido = ServicoPedido()
servicoPedido.servicoLogger = ServicoLogger()
servicoPedido.criarPedido() // Saída: Log: Pedido criado
Injeção por Métodos
A injeção por métodos permite que você passe dependências para um método quando ele é chamado. Isso é útil para dependências que são necessárias apenas em um contexto específico.
class ServicoEmail {
func enviarEmail(para destinatario: String) {
print("Email enviado para \(destinatario)")
}
}
class ServicoNotificacao {
func notificarUsuario(servicoEmail: ServicoEmail, para destinatario: String) {
servicoEmail.enviarEmail(para: destinatario)
}
}
// Uso
let servicoEmail = ServicoEmail()
let servicoNotificacao = ServicoNotificacao()
servicoNotificacao.notificarUsuario(servicoEmail: servicoEmail, para: "usuario@exemplo.com") // Saída: Email enviado para usuario@exemplo.com
Benefícios da Injeção de Dependência
- Testabilidade: Ao utilizar DI, você pode facilmente simular dependências, o que ajuda nos testes unitários.
- Flexibilidade: Você pode trocar facilmente implementações de suas dependências sem alterar a classe dependente.
- Manutenibilidade: Mudanças nas dependências são isoladas, facilitando a compreensão e a gestão do seu código.
Conclusão
A Injeção de Dependência é um poderoso padrão de design que simplifica a gestão de dependências em suas aplicações. Ao utilizar a injeção pelo construtor, injeção por propriedades ou injeção por métodos, você pode criar aplicações Swift modulares e testáveis. Escolha o método que melhor se adequa às suas necessidades e comece a aplicar os princípios de DI em seus projetos!