¿Qué es la daga 2 en Android?

Dagger 2 es una biblioteca para los proyectos de Android que implementan la plantilla de Inyección de dependencias. Hay varios artículos sobre cómo configurar Dagger 2, por lo que pensaré por qué esta biblioteca es importante y cómo ayuda.

La breve historia de Dagger 2

Dagger 1 fue creado por la compañía llamada Square (que también creó Retrofit, Picasso, okhttp y un montón de otras bibliotecas populares de Android). Después de eso, los desarrolladores de Google mejoraron y perfeccionaron Dagger 1 (por ejemplo, una reflexión obsoleta) dándole el nuevo nombre de Dagger 2. Estoy específicamente interesado en Dagger 2 y voy a escribir sobre él refiriéndome a él simplemente como “Dagger “.

La narrativa

La inversión de control es un principio importante de la programación orientada a objetos, que permite a los desarrolladores reducir el acoplamiento de componentes del sistema (fuerza de relación). Este principio a menudo se llama en broma el “Principio de Hollywood: no nos llames, nosotros te llamaremos a ti”.

La inyección de dependencias es una de las implementaciones de IoC que se aplican a la gestión de dependencias. Además de esto, hay plantillas como Factory o service Locator).

Los 99 problemas

Tomemos un ejemplo simple: cada proyecto de Android tiene uno o varios Singletons. Teniendo en cuenta la transitividad de los ciclos de vida de Actividad y Fragmento, apenas puede llevarse bien sin Singletons. Por lo general, llaman a este Singleton “el administrador bla-bla “, por ejemplo, ApplicationManager, DataManager o lo que sea. Este administrador generalmente almacena la API para el acceso al servidor, el objeto de acceso a datos (DAO) o la sesión para acceder a la base de datos local, y muchas otras cosas para otorgar a Activity and Fragment un fácil acceso a la lógica empresarial de la aplicación.

Esto lleva a un montón de problemas:

  • Las diferentes actividades y fragmentos requieren una funcionalidad diferente, lo que resulta en un Singletonbulking y se convierte en el llamado “Objeto de Dios” que almacena datos excesivos o hace demasiado. Esto rompe el principio de responsabilidad única.
  • Las actividades, fragmentos y otras clases que usan un Singleton de este tipo obtienen una dependencia implícita. No está presente en los constructores de campos de clase y necesita ver el código para encontrarlo.
  • Como resultado del punto anterior, las clases se unen estrechamente a un Singleton, lo que las hace inservibles y difíciles de probar. Es difícil aplicar cambios a dicho proyecto, ya que cualquier alteración puede causar efectos posteriores en cualquier otro lugar del proyecto.

Para evitar la impresión de que solo se trata del uso de Singletons, es justo decir que el problema es mucho más profundo que eso. Muchas veces los constructores de clases y los métodos onCreate de Actividades y Fragmentos se pueblan con otros objetos. Por ejemplo, hay SchedulerActivity que muestra un horario y otra clase, lo llamaremos SchedulerManager implementa la lógica del horario. La instancia de SchedulerManager probablemente se creará en el método onCreate de la actividad.

Este tipo de código tiene un problema: la clase SchedulerActivity está estrechamente vinculada a la clase SchedulerService:

  • No podrá escribir pruebas unitarias para SchedulerActivity en separación de SchedulerManager. De hecho, tendrá una prueba de integración en lugar de una prueba unitaria.
  • Si más adelante, necesitará varios administradores de horarios diferentes con la opción de cambiar entre ellos automáticamente, tendrá que volver a escribir SchedulerActivity.
  • Si SchedulerManager requiere configuraciones, deberá reconfigurarse en cada clase que lo use.

La solución

Entonces, ¿cómo ayudan Dependency Injection y Dagger a resolver estos y otros problemas similares?

De acuerdo con el principio de Responsabilidad Única, todas las preocupaciones sobre la construcción de las dependencias requeridas se delegan en lo externo y específicamente para este mecanismo, también conocido como Dagger. Debido a esto, los objetos que necesitan dependencias de la inicialización pueden obtenerlos automáticamente. Entonces, Dagger no es menos que una capa adicional capaz de “cortar” enlaces fuertes entre clases, haciendo que el código sea modular.

Así es como se verá SchedulerActivity si utiliza Dagger:

class SchedulerActivity: AppCompatActivity () {

@Inyectar
lateinit var SchedulerManager: SchedulerManager

anular la diversión onCreate (savedInstanceState: Bundle?) {
super.onCreate (savedInstanceState)
setContentView (R.layout.activity_scheduler)

application.daggerComponent.inject (this)
}
}

Con la ayuda de la anotación @Inject, le informamos a Dagger qué dependencias necesitamos y luego las solicitamos mediante la llamada application.daggerComponent.inject (this).

Aquí, SchedulerManager puede o no ser Singleton, no importa. SchedulerActivity no tiene idea de los detalles sobre su creación e inicialización. Todas estas preocupaciones pasan a la configuración de Dagger. Podemos sustituir fácilmente la implementación de SchedulerManager con un código auxiliar para escribir pruebas unitarias.

Dagger también crea la opción de proporcionar tantas dependencias como desee. No es necesario tener un Singleton divino que almacene toda la funcionalidad de Actividades y Fragmentos para obtener acceso a él. Puede asignar y agrupar fácilmente las funciones funcionales de acuerdo con las necesidades de las diferentes partes del proyecto.

Dagger es un marco de inyección de dependencia de tiempo de compilación totalmente estático para Java y Android. Es una adaptación de una versión anterior creada por Square y ahora mantenida por Google.

Dagger tiene como objetivo abordar muchos de los problemas de desarrollo y rendimiento que han afectado a las soluciones basadas en la reflexión. Gregory Kick puede encontrar más detalles en esta charla (diapositivas).