java - settitle - ¿Por qué la gente usa buses de mensaje/evento en su código?
para que sirve settitle en java (7)
Creo que has oído hablar de los buses de mensajes / eventos, es el único lugar donde fluyen todos los eventos en el sistema. Arquitecturas similares se encuentran en las placas base de la computadora y redes LAN. Es un buen enfoque para placas base y redes, ya que reduce la cantidad de cables, pero ¿es bueno para el desarrollo de software? No tenemos restricciones como las electrónicas.
La implementación más simple del bus de mensajes / bus de eventos puede ser como:
class EventBus {
void addListener(EventBusListener l}{...}
void fireEvent(Event e) {...}
}
La publicación de eventos se realiza con bus.fireEvent (evento), la recepción de mensajes es habilitada por bus.addListener (listener). Tales arquitecturas a veces se utilizan para el desarrollo de software, por ejemplo, MVP4G implementa un bus de mensajes similar para GWT.
Proyectos activos:
- Google Guava EventBus
- MBassador de Benjamin Diedrichsen
- Mycila PubSub por Mathieu Carbou
- Bus de eventos mvp4g
- Simple Java Event Bus
Proyectos inactivos / muertos:
- Sun / Oracle JavaBeans InfoBus
- https://eventbus.dev.java.net/ [Enlace roto]
Es solo el popular patrón Observer (Listener) hecho ''globalmente'' - cada objeto en el sistema puede escuchar cada mensaje, y creo que es malo, rompe el principio de Encapsulación (cada objeto conoce todo) y el principio de Responsabilidad Individual (por ejemplo, cuando algún objeto necesita un nuevo tipo de mensaje, el bus de eventos a menudo necesita ser cambiado, por ejemplo, para agregar una nueva clase de Oyente o un nuevo método en la clase de Oyente).
Por estas razones, creo que para la mayoría del software, el patrón Observer es mejor que el bus de eventos. ¿Qué piensas del bus de eventos? ¿Tiene sentido para las aplicaciones típicas?
EDITAR: No estoy hablando de soluciones empresariales ''grandes'' como ESB: pueden ser útiles (además, ESB ofrece mucho más que solo un bus de eventos). Pregunto acerca de la utilidad de usar el bus de mensajes en el código Java "regular" para la conexión de objeto a objeto. Algunas personas lo hacen, verifique los enlaces de arriba. El bus de eventos es probablemente la mejor solución para las comunicaciones de teléfono a teléfono o de computadora a computadora porque cada teléfono (o computadora) en una red generalmente puede comunicarse entre sí, y el autobús reduce la cantidad de cables. Pero los objetos rara vez se hablan entre sí, ¿cuántos colaboradores puede tener un objeto? ¿3, 5?
A algunas personas les gusta porque es la encarnación del patrón de Fachada o el patrón de Mediator . Centraliza actividades transversales como registro, alerta, monitoreo, seguridad, etc.
Algunas personas no les gusta porque a menudo es un punto de falla de Singleton. Todos deben saber sobre eso.
Como ejemplo práctico, nuestra sincronización de aplicaciones con un servicio web cada x número de minutos, y si se reciben datos nuevos, debemos actualizar la GUI. Ahora, como SyncAdapter se ejecuta en una cadena de fondo, no puede simplemente señalar una vista de texto y modificar sus propiedades, debe crear un evento. Y la única forma de asegurarse de atrapar ese evento es si tiene un objeto compartido (estático, único) que pase ese evento para que lo manejen los suscriptores.
Estoy considerando usar un Bus de eventos en memoria para mi código regular de Java y mi razonamiento es el siguiente
Cada objeto en el sistema puede escuchar cada mensaje, y creo que es malo, rompe el principio de encapsulación (cada objeto lo sabe todo)
No estoy seguro de si esto es realmente cierto, la clase necesita registrarse con el bus de eventos para comenzar, similar al patrón del observador. Una vez que una clase se ha registrado con el bus de eventos, solo se notifican los métodos que tienen la firma y la anotación adecuadas. .
y el principio de Responsabilidad individual (por ejemplo, cuando un objeto necesita un nuevo tipo de mensaje, el bus de eventos a menudo necesita ser cambiado, por ejemplo, para agregar una nueva clase de Oyente o un nuevo método en la clase de Oyente).
Estoy totalmente en desacuerdo con
el bus de eventos a menudo necesita ser cambiado
El bus de eventos nunca cambia
estoy de acuerdo con
add a new Listener class or a new method in the Listener class
¿Cómo rompe esto SRP?, Puedo tener un BookEventListener que se suscriba a todos los eventos pertenecientes a my Book Entity, y sí, puedo agregar métodos a esta clase, pero aún así esta clase es cohesiva ...
¿Por qué planeo usarlo? Me ayuda a modelar el "cuándo" de mi dominio ...
Por lo general, escuchamos algo como enviar un correo "cuando" se compra el libro
vamos a escribir
book.purchase();
sendEmail()
Luego nos dicen que agreguemos un registro de auditoría cuando se compra un libro, vamos al fragmento de arriba
book.purchase();
sendEmail();
**auditBook();**
Justo allí OCP violó
Yo prefiero
book.purchase();
EventBus.raiseEvent(bookPurchasedEvent);
Luego siga agregando controladores según sea necesario. Abra la extensión cerrada para la modificación.
Gracias
Lo uso mucho en JavaScript. Puede haber tantos widgets distintos que todos necesiten realizar algún tipo de acción cada vez que ocurra algo más: no existe una verdadera jerarquía de propiedad de los objetos. En lugar de pasar referencias de cada objeto a cada objeto, o simplemente hacer que cada objeto sea global, cuando sucede algo significativo dentro de un widget en particular, puedo publicar "/ thisWidget / somethingHappened" - en lugar de llenar ese widget con todo tipo de códigos específicos a la API de otros widgets. Tengo una única clase que contiene todo el "cableado" o "plubming", como les gusta llamarlo en el marco de Java Spring. Esta clase contiene referencias a todos mis widgets, y tiene todo el código de lo que ocurre después de cada evento de incendios.
Es centralizado, de fácil acceso y mantenimiento, y si algo cambia o quiero que ocurra un nuevo proceso en un evento específico, no tengo que buscar en cada clase / objeto / artilugio para tratar de encontrar algo está siendo manejado. Puedo ir a mi clase de "operador", la que maneja todo el "cableado" cuando ocurre un evento en particular, y ve todas las repercusiones de ese evento. En este sistema, cada widget individual es completamente independiente de API de los otros widgets. Simplemente publica lo que le sucedió o lo que está haciendo.
Porque puede ser un paso importante en el camino para desacoplar los módulos de la aplicación a una arquitectura basada en servicios .
Entonces, en su caso, si no tiene la intención de desacoplar los módulos de su aplicación en servicios aislados, la implementación nativa del patrón Observer lo convertirá en una solución más simple.
Pero si quiere construir, digamos una arquitectura de micro servicios, event-bus le permitirá obtener los beneficios de este estilo arquitectónico, de modo que pueda, por ejemplo, actualizar y desplegar solo una parte de su aplicación sin afectar a otras, porque solo están conectadas. a través del evento-bus.
Entonces, la pregunta principal aquí es el nivel deseado de desacoplamiento de los componentes de la aplicación .
Algunas referencias al respecto:
Tengo problemas para entender lo que realmente preguntas en tu pregunta. Usted da un ejemplo de un simple bus de eventos que en realidad es solo Observable
con un nombre diferente, entonces usted dice;
Por estas razones, creo que para la mayoría del software, el patrón Observer es mejor que el bus de eventos. ¿Qué piensas del bus de eventos? ¿Tiene sentido para las aplicaciones típicas?
..pero dado tu ejemplo, son lo mismo. Esto me hace preguntarme si alguna vez ha usado algo así como un Enterprise Service Bus. A nivel de base, un ESB lógicamente hace lo mismo que el patrón de observador, pero los productos comerciales agregan mucho, mucho más. Es como un autobús de eventos con esteroides. Son productos y ofertas de software complicados;
Recogida de mensajes
Genere eventos escuchando varios puntos finales. El punto final puede ser un oyente (como un servidor HTTP), un sistema de mensajería (como JMS), una base de datos o prácticamente cualquier otra cosa que desee.
Enrutamiento de mensajes
Tome su evento y envíelo a uno / muchos punto final. El enrutamiento puede ser bastante inteligente, el bus puede enrutar el mensaje dependiendo del tipo de mensaje, el contenido del mensaje o cualquier otro criterio. El enrutamiento puede ser inteligente y dinámico.
Transformación de mensajes
Transforma su mensaje a otro formato, esto puede ser tan simple como de XML a JSON o de una fila en una tabla de base de datos a una solicitud HTTP. La transformación puede ocurrir dentro de los datos en sí, por ejemplo, intercambiando formatos de fecha.
Enriquecimiento de datos
Agrega o modifica datos en su mensaje llamando a los servicios en el camino. Por ejemplo, si un mensaje tiene un código postal, el bus podría usar un servicio de búsqueda de código postal para agregar datos de dirección.
..y mucho, mucho más. Cuando comienzas a buscar los detalles, realmente puedes comenzar a ver por qué las personas usan estas cosas.
Una buena analogía es la de una central telefónica, donde cada teléfono puede marcar a cualquier otro teléfono. Un teléfono comprometido puede sintonizar otras conversaciones. El control del programa fluye como los cables (¡cualquier complejidad ciclomática!) Esto es similar al requisito de tener una conexión / medio físico entre dos puntos finales. Esto es así para los teléfonos N en lugar de tener flujos NC2 (lógica combinatoria) para cada teléfono nuevo, tendemos a obtener N flujos.
Una reducción en la complejidad implica un código fácil de entender. Comencemos con los puntos destacados que ha resaltado: 1. Conocimiento global 2. Modificaciones intrusivas.
Conocimiento global: Considere que el evento del mensaje es un sobre. Desde la perspectiva del controlador de eventos / remitente no se muestran datos, está viendo un sobre (a menos que una clase derivada intente hacer una inspección usando verificaciones ''instancia de''). En un buen diseño de OOP, esto nunca ocurriría.
Modificaciones intrusivas: en lugar de tener un enfoque de oyente específico para el evento, se puede usar un enfoque global de manejo de eventos. Como tal, tenemos un tipo de evento global (en el que los datos se respaldan y se descifran). Esto es muy parecido al modelo de PropertyBeanSupport en Java. Con un solo tipo de evento, se requiere que tengamos un único emisor y tipos de oyentes. Esto implica que no necesita modificar el bus / oyentes cada vez que vea algo nuevo. El feo down-casting puede suavizarse usando el patrón Adapter (¡No empieces otro nivel de citación de redirección!). Los programadores pueden escribir el ensamblaje en cualquier idioma. De modo que la necesidad del sentido común y la inteligencia no pueden ser sustituidos. Todo lo que pretendo decir es que puede ser una herramienta efectiva.
Los receptores de eventos reales pueden usar los oyentes (composición / proxy) fácilmente. En dicha base de código Java, los oyentes se verían como declaraciones independientes de clase interna (con advertencia no utilizada marcada en ciertos IDE). Esto es así para dos jugadores en la playa jugando un juego de pelota, los jugadores no reaccionan hasta que ven la pelota.
''@duffymo'' señala otro aspecto interesante: ''Single point of failure''. Esto / podría, en teoría, afectar a cualquier objeto que resida en la memoria (RAM) y que no sea específico de MessageHandlers.