Ventajas de inyectar el autobús de eventos de Otto en lugar de usar singleton estático
En mis aplicaciones de Android estoy usando Otto como bus de eventos y Dagger para la inyección de dependencia.
En el userguide de Otto y en muchos blogs se recomienda usar la inyección para obtener un bus singleton. He hecho eso por algún tiempo, pero últimamente estoy consiguiendo más dudoso si inyectando el autobús tiene ventajas sobre usar un singleton estático simple.
- ¿Cómo enviar un evento de Servicio a Actividad con el bus de eventos Otto?
- Mejores Prácticas para el Manejo de la Búsqueda
- RuntimeException: No se pudo enviar evento @ otto
- Evento Otto sin disparos
- Model View Presenter con un EventBus, ¿cómo recuperar los eventos en Presenter?
Con la inyección tengo que inyectar cada vista de encargo o ViewHolder que quiero poder fijar acontecimientos de UI en el megabus. Especialmente con la daga parece un poco torpe inyectar cada clase donde necesito el autobús. Claro, yo podría pasar el autobús por constructor o método setter, pero que puede ser un poco torpe también si se piensa en un adaptador con muchos tipos de vista diferentes, por ejemplo.
Y no veo ninguna ventaja en la inyección del autobús. En caso de Otto se inyecta una implementación concreta (una instancia de Bus) y eso nunca cambiará. Envoltura Otto para desacoplamiento no tiene ningún sentido si piensa, debido a la forma de suscripción funciona.
Entonces, ¿alguien ve las ventajas de inyectar Otto que no veo?
- RxAndroid, bus de eventos y ciclo de vida de la actividad
- Problema de suscripción de bus de eventos (bus de eventos Otto - Guava)
- NullPointerException con Otto y Dagger
- Otto / EventBus a través de múltiples procesos
- ¿Qué métodos de ciclo de vida de actividad son los mejores para registrar / anular el registro en el bus de eventos?
- Issue Suscribiéndose a / Receiving Otto Event Publicado desde IntentService
- Reducción del número de clases de eventos al utilizar EventBus o Otto
- Otto lanza "Objeto ya registrado" onResume en viewpager
En mi opinión, usted debe definitivamente envolver el autobús de eventos en su propia clase y el uso de técnicas de inyección de dependencia con el fin de pasar a los clientes.
Hay varias ventajas a este enfoque sobre simplemente obtener una referencia a través de una llamada al método estático getInstance()
:
- Sus dependencias se vuelven explícitas. Cuando obtiene referencias a objetos a través de llamadas estáticas, las dependencias se ocultan dentro de la implementación de los clientes, lo que hace que el código sea más frágil y difícil de entender.
- Será más fácil cambiar a una implementación diferente del bus de eventos si surge tal necesidad.
- Las dependencias inyectadas son más fáciles de simular en las pruebas
- El hecho de que las técnicas de inyección de dependencia introducir algún grado de lucha es en realidad una buena cosa – si usted está luchando, esto es a menudo una indicación de que está haciendo algo mal. En su caso, sospecho que está abusando del autobús de eventos.
Digo que es posible que esté abusando de un autobús de eventos porque realmente no veo por qué necesitaría tener una referencia a él en las subclases View
. Supongo que publicar notificaciones sobre las interacciones de los usuarios con el bus de eventos y, a continuación, suscribirse Activity
o Fragment
al bus de eventos con el fin de interceptar estos eventos. El autobús de eventos es una herramienta incorrecta en este caso (aunque funciona muy bien).
La razón por la cual el bus de eventos es una herramienta incorrecta en este caso es porque Fragments
y Activity
pueden tener acceso directo a los objetos de View
contenidos. Puede obtener referencias a estas Views
y registrar Fragments
y Activities
como oyentes. No hay necesidad de desacoplar nada aquí.
Por el contrario: piense en un caso en el que vaya y refactorice sus Views
de tal manera que nada se publique en el autobús de eventos (digamos, los requisitos de negocio cambian). Dado que las notificaciones de Views
sólo se suelen acoplar a Fragment
o Activity
través del bus de eventos, es muy probable que se olvide de eliminar los eventos que manejan la lógica de Fragment
y Activity
, dejando así "código muerto" atrás. Esto se ensucia muy rápidamente.
La mejor práctica sería utilizar el patrón de diseño Observer y dejar que Views
notifiquen las Activities
y Fragments
directamente, y sólo cuando el manejo involucre otro componente (que no puede ser fácilmente alcanzado desde Fragment
y Activity
, por ejemplo, otro Fragment
o Activity
) Al autobús del acontecimiento. Si sigue este enfoque, necesitará tener una referencia al bus de eventos en "componentes de nivel superior" únicamente y no habrá problemas.
PS Recientemente he publicado una entrada en el blog que introduce algunas prácticas recomendadas para la inyección de la dependencia en Android .
- Tamaño de icono de la barra de estado de Android – Uso de Cordova / Phonegap Push Plugin
- Cambiar el color del cursor editext en API 12