Middle
Para que é que se utiliza a injeção de dependências em aplicações Android?
sobes.tech IA
Resposta da IA
A injeção de dependências (DI) é usada em aplicações Android para decompor o código, melhorar a testabilidade e facilitar a refatoração. Permite que os componentes obtenham dependências de fontes externas em vez de as criarem por si próprios.
Os principais objetivos do uso de DI em Android:
- Acoplamento reduzido: Os componentes tornam-se menos ligados entre si. Alterar uma dependência não requer modificar o componente que a utiliza.
- Testabilidade: É fácil substituir implementações de teste (mocks, fakes) ao escrever testes unitários.
- Gestão do ciclo de vida: Os frameworks DI podem gerir a criação e destruição de objetos, garantindo ciclos de vida adequados para as dependências, especialmente relevante no Android com seus ciclos de vida específicos de Activities, Fragments, etc.
- Reutilização: As dependências podem ser facilmente reutilizadas por diferentes componentes da aplicação.
- Simplificação do código: O código torna-se mais limpo e compreensível, pois não é necessário criar e passar dependências manualmente através de construtores ou setters.
Exemplos de frameworks DI em Android: Hilt (recomendado pelo Google), Dagger, Koin.
Exemplo (pseudocódigo sem DI):
// Classe que cria uma dependência internamente
class UserRepository {
private val apiService = ApiService() // Criação interna de dependência
fun getUser(id: Int): User {
return apiService.fetchUser(id)
}
}
class ApiService {
fun fetchUser(id: Int): User {
// Lógica para obter dados
return User(id, "John Doe")
}
}
data class User(val id: Int, val name: String)
Exemplo (pseudocódigo com DI):
// Classe que recebe a dependência através do construtor
class UserRepository(private val apiService: ApiService) {
fun getUser(id: Int): User {
return apiService.fetchUser(id)
}
}
class ApiService {
fun fetchUser(id: Int): User {
// Lógica para obter dados
return User(id, "Jane Doe")
}
}
data class User(val id: Int, val name: String)
// Em algum lugar no código, onde ocorre a configuração de DI:
// val apiService = ApiService()
// val userRepository = UserRepository(apiService)
No último exemplo, UserRepository não sabe como criar ApiService, ele simplesmente a recebe de fora. Isso facilita substituir ApiService por uma versão de teste ao testar UserRepository.