¿Por qué utilizar la inyección de dependencia? ¿No es bueno crear objetos nuevos directamente? ¿Por qué complicar un problema simple?

Autor: newki

¿Por qué utilizar la inyección de dependencia? ¿No es bueno crear objetos nuevos directamente? ¿Por qué complicar un problema simple?

¿Estás mostrando tus habilidades o finges tener 13 años?

Este realmente no es el caso, si el Dagger2 que uso es realmente un alarde, NB. Dagger también tiene muchos inconvenientes. Es realmente increíble usar Dagger bien en proyectos grandes, pero ahora todos usamos Hilt. ¿Qué podemos instalar? Es realmente simple de usar y todo está basado en escenas. Algunas cosas solucionadas uso. No es necesario, no es necesario.

Volviendo al tema, ¿por qué utilizar la inyección de dependencia? ¿Cuándo se recomienda la inyección de dependencia? Incluso si desea utilizar la inyección de dependencia, ¿por qué se recomienda Hilt para la inyección de dependencia?

1. Gestión automática (flexibilidad y desacoplamiento)

En primer lugar, esto no significa que deba usar la inyección de dependencia al escribir un proyecto. Si su proyecto no es un proyecto grande, solo hay 5, 6 o más de 10 páginas en total. No necesita usar Un marco de inyección de dependencia. Si es un proyecto grande, divídalo en módulos. Los componentes son desarrollados conjuntamente por varias personas y los objetos que pueden depender de ellos son muy complicados, o dependencias de objetos como muñecos anidados, por lo que es muy conveniente de usar. Empuñadura. Los desarrolladores de diferentes módulos/componentes definen directamente el método de provisión de objetos en sus propios componentes/módulos y lo utilizan directamente en el otro lado, sin la complejidad de las dependencias relacionales y la lógica de implementación.

Echemos un vistazo a algunas dependencias anidadas complejas, por ejemplo, tomemos una dependencia de muñeca de tres capas:

@Singleton
class UserServer @Inject constructor(private val userDao: UserDao) {

    fun testUser() {
        YYLogUtils.w(userDao.printUser())
        toast(userDao.printUser())
    }

    fun getDaoContent():String{
        return userDao.printUser()
    }

}

@Singleton
class UserDao @Inject constructor(private val user: UserBean) {

    fun printUser(): String {
        return user.toString()
    }

}

data class UserBean(
    val name: String,
    val age: Int,
    val gender: Int,
    val languages: List<String>
)

Las otras tres clases son todas necesarias, de hecho, hay una clase más que proporciona objetos UserBean.

@Module
@InstallIn(SingletonComponent::class)
class Demo10DIModule {

    @Singleton
    @Provides
    fun provideUser(): UserBean {
        return UserBean("newki", 18, 1, listOf("中文", "英文"))
    }

}

usar:

@AndroidEntryPoint
class Demo10DIActivity : BaseVMActivity() {

    @Inject
    lateinit var userServer: UserServer

    override fun getLayoutIdRes(): Int = R.layout.activity_demo10_di

    override fun init() {
        findViewById<Button>(R.id.btn_01).click {
            YYLogUtils.w(userServer.toString())
            userServer.testUser()
        }
    }

Si no usa Hilt, también puede implementar su propio objeto nuevo

class Demo10DIActivity : BaseVMActivity() {

    lateinit var userServer: UserServer

    override fun getLayoutIdRes(): Int = R.layout.activity_demo10_di

    override fun init() {
        //自己new三个对象
         userServer = UserServer(UserDao(UserBean("newki", 18, 1, listOf("中文", "英文"))))

        findViewById<Button>(R.id.btn_01).click {
            YYLogUtils.w(userServer.toString())
            userServer.testUser()
        }
    }

De esta manera, el nuevo objeto, sin mencionar que el ciclo de vida sigue a la página, no puede mantener una sola instancia. Digamos que si los requisitos cambian, UserBean y UserProfile son necesarios en UseDao. Si es un objeto nuevo, necesita para modificarlo en todas partes, si es el método Hilt, solo necesitamos modificar la estructura del objeto UserDao

@Singleton
class UserDao @Inject constructor(private val user: UserBean,private val profile:UserProfile) {

    fun printUser(): String {
        return user.toString()
    }

}

Lo anterior es solo un ejemplo simple: para construir un objeto, necesita construir un montón de otros objetos, y la construcción de otros objetos es igualmente complicada y debe construirse en orden, y los ciclos de vida de los objetos requeridos son diferentes. Algunos ciclos de vida pueden ser diferentes de Like Activity, algunos pueden ser únicos, por lo que el ciclo de vida del objeto y el origen del objeto también deben considerarse al construir.

Especialmente en proyectos a gran escala, es muy doloroso, porque el proyecto no lo escribe una sola persona y todos cooperan para desarrollarlo. Mirar el código de otras personas es como leer la Biblia y no sabes cómo funciona el objeto. Se crea el colega. Si se produce el método de construcción de un objeto, los cambios afectarán todo el proceso de construcción y los códigos asociados, y afectarán a todo el cuerpo.

En este momento, el marco de inyección de dependencias es útil. Solo necesitamos enfocarnos en cómo implementar funciones, dependencias de objetos y ciclos de vida, y dejar que él lo administre por nosotros. Un Inject nos ayudará a inyectar lo que necesitamos de acuerdo con las dependencias. Objeto, y gestionará el ciclo de vida de cada objeto, y no repetirá nada nuevo cuando el ciclo de vida no haya terminado.

Por lo tanto, la inyección de dependencia de Hilt es muy adecuada para proyectos grandes. Los desarrolladores de proyectos pequeños no han encontrado estos problemas debido a la baja complejidad del proyecto, por lo que no entienden por qué se usa la inyección de dependencia de Hilt y preguntan por qué deberían usarse nuevos objetos simples. ser tan complicado.

2. Control del ciclo de vida

El ciclo de vida del objeto mencionado aquí es en realidad el ciclo de vida en un determinado alcance, si es demasiado superficial decir que un singleton es un singleton dentro de un cierto rango.

No podemos controlar el ciclo de vida del nuevo objeto directamente, a menos que usemos el objeto singleton global, y podemos implementar fácilmente el control del ciclo de vida del objeto mediante la inyección de dependencia de Hilt.

Por ejemplo, en el método de inyección rápida de nuestros objetos ordinarios, anotar directamente Singleton marcará el singleton de alcance global.

@Singleton
class UserServer @Inject constructor(private val userDao: UserDao) {

    fun testUser() {
        YYLogUtils.w(userDao.printUser())
        toast(userDao.printUser())
    }

    fun getDaoContent():String{
        return userDao.printUser()
    }

}

Otro uso es que usamos Módulo para definir la inyección de dependencia, luego usar SingletonComponent + Singleton también significa singleton de alcance global

@Module
@InstallIn(SingletonComponent::class)
class Demo10DIModule {

    @Singleton
    @Provides
    fun provideUser(): UserBean {
        return UserBean("newki", 18, 1, listOf("中文", "英文"))
    }

}

Si queremos un singleton en la Actividad, usamos ActivityComponent + ActivityScoped, que es un singleton en el alcance de la Actividad.

@Module
@InstallIn(ActivityComponent::class)
class Demo10DIModule {

    @ActivityScoped
    @Provides
    fun provideUser(): UserBean {
        return UserBean("newki", 18, 1, listOf("中文", "英文"))
    }

}

Los dos anteriores son ámbitos de uso relativamente común. Para otros, también podemos asegurarnos de que los singleton en Fragment y los singleton en View se usen de la misma manera.

Por lo tanto, el control del ciclo de vida de los objetos dependientes también es una característica muy conveniente de Hilt, que no se puede lograr mediante el uso de objetos nuevos.

3. Comparado con otras inyecciones de dependencia

En la actualidad, la corriente principal de Android son tres tipos de inyección de dependencia Dagger2 Hilt Koin.

En comparación con Koin antes, solo se puede usar en el entorno del lenguaje Kotlin. Y el rendimiento no será mejor que el de Hilt. El mensaje de error tampoco es amigable.

Dagger2 no es inutilizable. Fue muy popular en 2017 y 2018, pero el costo de aprendizaje es muy alto. Cada vez que crea una clase de inyección de dependencia de UI, debe realizar un mackproject y el mensaje de error no es amigable.

De hecho, he estado usando Dagger2 durante 17 años, y luego hice la demostración y el paquete de marco yo mismo, pero no los usé en el proyecto más tarde. Una es que hay demasiadas trampas y la otra es que Mis colegas no saben cómo usarlo y el costo de aprendizaje es demasiado alto. También deja de usar Dagger2.

Hilt es en realidad la implementación del escenario de Android de Daggert2. Dagger2 está encapsulado internamente. Es más fácil usar Hilt en el desarrollo de Android, el costo de aprendizaje es muy bajo y el mensaje de error es amigable. Y también se puede inyectar en ViewModel. Por eso está diseñado para el desarrollo de Android.

Con respecto a si el uso de la memoria de los objetos inyectados está optimizado, no hay artículos ni documentos oficiales que indiquen que existe una optimización de la memoria. Solo mi propia prueba muestra que si hay varios objetos inyectados en toda la página en comparación con los nuevos objetos directos, siento que el objeto inyectado ocupa un poco menos de memoria, no sé si es la fluctuación de la prueba, no lo entiendo.

Resumir

Resuma por qué debería utilizar Hilt.

  1. Pereza; gestión automática, inyección automática de múltiples objetos, en caso de que haya una modificación, no hay necesidad de quedarse tirado en la montaña de cadáveres.
  2. Singleton; dejar que el objeto tenga un ciclo de vida, sin nuestra propia creación manual de singleton, y luego cerrar sesión manualmente.
  3. Desacoplamiento; no necesito introducir algunos objetos innecesarios en todas partes, especialmente para proyectos en componentes, otro componente simplemente inyecta y solo hago referencia en mi componente.

Creo que estos son los tres puntos que más me atraen cuando uso Hilt,

Ahora estamos en 2022 y recomiendo Hilt para la inyección de dependencia. La clave es fácil de usar. También hice algunas demostraciones en los escenarios comunes de Android. Hay tantos usos fijos en total. Escribí una demostración antes que cubre la mayoría de los escenarios de uso del desarrollo de Android. Si lo necesita, puede Puedes tomarlo directamente, puedes consultarlo en mi artículo anterior.

Por cierto, esta es una habilidad de entrevista necesaria para los programadores extranjeros. En comparación con los desarrolladores nacionales, a los desarrolladores extranjeros de Android les gusta especialmente usar Dagger2 y Hilt. Muchos proyectos antiguos usan Dagger2.

notas de estudio de Android

Optimización del rendimiento de Android: https://qr18.cn/FVlo89
Android Vehículo: https://qr18.cn/F05ZCM
Android Notas de estudio de seguridad inversa: https://qr18.cn/CQ5TcL
Principios del marco de trabajo de Android: https://qr18.cn/AQpN4J
Android Audio y video: https://qr18.cn/Ei3VPD
Jetpack (incluido Compose): https://qr18.cn/A0gajp
Kotlin: https://qr18.cn/CdjtAF
Gradle: https://qr18.cn/DzrmMB
OkHttp Notas de análisis del código fuente: https://qr18.cn/Cw0pBD
Flutter: https://qr18.cn/DIvKma
Android Eight Knowledge Body: https://qr18.cn/CyxarU
Android Core Notes: https://qr21.cn/CaZQLo
Android Preguntas de entrevistas anteriores: https://qr18.cn/CKV8OZ
Última colección de preguntas de entrevistas de Android de 2023: https://qr18.cn/CgxrRy
Ejercicios de entrevistas de trabajo de desarrollo de vehículos Android: https://qr18.cn/FTlyCJ
Preguntas de entrevistas de audio y video:https://qr18.cn/AcV6Ap

Supongo que te gusta

Origin blog.csdn.net/weixin_61845324/article/details/132494653
Recomendado
Clasificación