Pourquoi les gens utilisent les bus de messages/événements dans leur code?
je pense que vous avez entendu parler des bus de messages/événements, c'est le seul endroit où tous les événements dans le système circulent. Des architectures similaires se retrouvent dans les cartes mères des ordinateurs et les réseaux LAN. C'est une bonne approche pour les cartes mères et cartes réseaux, car elle réduit le nombre de fils, mais c'est bon pour le développement de logiciel? Nous n'avons pas les mêmes restrictions que l'électronique.
l'implémentation la plus simple du bus de messages / bus d'événements peut ressembler à:
class EventBus {
void addListener(EventBusListener l}{...}
void fireEvent(Event e) {...}
}
affichage des événements est fait avec le bus.fireEvent (événement), la réception des messages est activée par bus.addListener (écouter). De telles architectures sont parfois utilisées pour le développement de logiciels, par exemple MVP4G implémente un bus de messages similaire pour GWT.
projets actifs:
- Google Guava EventBus
- MBassador by Benjamin Diedrichsen
- Mycila PubSub by Mathieu Carbou
- mvp4g Événement Bus
- Java Simple Événement De Bus
projets inactifs / morts:
- Sun / Oracle JavaBeans InfoBus
- https://eventbus.dev.java.net/ [lien Brisé]
c'est juste le modèle D'Observateur populaire (auditeur) fait 'globalement' - chaque objet dans le système peut écouter chaque message, et je pense qu'il est mauvais, il brise le principe D'Encapsulation (chaque objet sait à propos de tout) et le principe de Responsabilité Unique (par exemple, quand un objet a besoin d'un nouveau type de message, le bus d'événement a souvent besoin d'être changé par exemple pour ajouter une nouvelle classe D'auditeur ou un nouveau méthode dans la classe Écouteur).
pour ces raisons, je pense que pour la plupart des logiciels, le modèle de L'observateur est meilleur que le bus d'événements. Que pensez-vous du bus événementiel, est-ce que cela a un bon sens pour des applications typiques?
EDIT: Je ne parle pas des "grandes" solutions d'entreprise comme ESB - elles peuvent être utiles (ce qui est plus ESB offre beaucoup, beaucoup plus qu'un simple bus d'événement). Je pose des questions sur l'utilité d'utiliser le bus de messages dans le code Java "régulier" pour d'objet à objet de connexion - certaines personnes le font, vérifiez les liens ci-dessus. Event bus est probablement la meilleure solution pour la communication de téléphone à téléphone ou de l'ordinateur à l'ordinateur de communication parce que chaque telefone (ou ordinateur) dans un réseau peut généralement parler à l'autre, et bus réduit le nombre de fils. Mais les objets se parlent rarement - combien de collaborateurs un objet peut - il avoir-3, 5?
7 réponses
certaines personnes l'aiment parce qu'il est l'incarnation du modèle de façade ou modèle Médiateur . Il centralise les activités transversales comme la journalisation, l'alerte, la surveillance, la sécurité, etc.
certaines personnes ne l'aiment pas parce que c'est souvent un seul point d'échec. Tout le monde a à savoir sur le sujet.
j'envisage d'utiliser un Bus D'événements en mémoire pour mon code java régulier et ma raison d'être est la suivante
chaque objet dans le système peut écouter chaque message, et je pense que c'est mauvais, il rompt le principe d'Encapsulation (chaque objet connaît tout)
Je ne suis pas sûr que ce soit vraiment vrai, I classe doit s'inscrire avec le bus d'événement pour commencer, similaire à observer pattern, une fois qu'une classe A enregistrés avec le Bus D'événements, seules les méthodes qui ont la signature et l'annotation appropriées sont notifiées.
et le principe de la responsabilité unique (par exemple lorsqu'un objet a besoin d'un nouveau type de message, event bus doit souvent être changé par exemple pour ajouter une nouvelle classe D'écoute ou une nouvelle méthode dans la classe D'écoute).
je suis totalement en désaccord avec
bus événement a souvent besoin à changer
le bus de l'événement n'est jamais changé
je suis d'accord avec
add a new Listener class or a new method in the Listener class
Comment est-ce que cette rupture SRP ?, Je peux avoir un BookEventListener qui souscrit à tous les événements relatifs à mon entité de livre, et oui je peux ajouter des méthodes à cette classe, mais encore cette classe est cohésive ...
pourquoi je prévois de l'utiliser ? Cela m'aide à modéliser le "quand" de mon domaine ....
Habituellement nous entendre quelque chose comme envoyer un courrier "quand " le livre est acheté
nous allons écrire
book.purchase();
sendEmail()
alors on nous dit Ajouter un journal de vérification quand un livre est acheté , nous allons à l'extrait ci-dessus
book.purchase();
sendEmail();
**auditBook();**
là OCP violé
Je Préfère
book.purchase();
EventBus.raiseEvent(bookPurchasedEvent);
puis continuer à ajouter des manipulateurs au besoin ouvert pour L'Extension fermé pour Modification
Merci
Je l'utilise lourdement en JavaScript. Il peut y avoir tellement de différents widgets que tous ont besoin de faire une sorte d'action chaque fois que quelque chose d'autre se produit -- il n'y a pas de véritable hiérarchie de la propriété des objets. Au lieu de passer des références de chaque objet à chaque objet, ou simplement de rendre chaque objet global, quand quelque chose d'important se produit à l'intérieur d'un widget particulier, je peux juste publier "/thisWidget/somethingHappened" -- au lieu de remplir ce widget avec toutes sortes de code spécifique au API d'autres widgets. J'ai une seule classe qui contient tout le "câblage", ou "plubming" comme ils aiment l'appeler dans le Java Spring framework. Cette classe contient des références à tous mes widgets, et a tout le code pour ce qui se passe après chaque Divers feux d'événement.
il est centralisé, facile d'accès et de maintenance, et si une chose change ou si je veux qu'un nouveau processus se produise sur un événement spécifique, je n'ai pas à chercher à travers chaque classe/objet/widget pour essayez de trouver où quelque chose est manipulé. Je peux juste aller à ma classe "opérateur" -- celle qui gère tout le" câblage " quand un événement particulier se produit, et voir toutes les répercussions de cet événement. Dans ce système, chaque widget individuel est complètement agnostique API des autres widgets. Il publie simplement ce qui lui est arrivé ou ce qu'il fait.
j'ai du mal à comprendre ce que vous êtes vraiment dans votre question. Vous donnez un exemple d'un bus d'événement simple qui est en fait juste Observable
avec un nom différent, puis vous dites;
Pour ces raisons, je pense, que pour la plupart des logiciels, modèle Observateur est meilleur que le bus de l'événement. Que faites-vous pensez au bus de l'événement, est-ce qu'il fait tout bon sens typique les applications?
..mais avec votre exemple, ils sont les mêmes. Cela me fait me demander si vous avez déjà utilisé quelque chose comme un Bus de service D'entreprise. Au niveau de la base, un ESB fait logiquement la même chose que le modèle de l'observateur, mais les produits commerciaux ajoutent beaucoup, beaucoup plus. Son comme un événement de bus sur les stéroïdes. Ce sont des produits et des offres logiciels complexes;
messagerie
Générer des événements en écoutant divers paramètres. Le point final peut être un écouteur (tel QU'un serveur HTTP), un système de messagerie (tel que JMS), une base de données ou à peu près tout ce que vous voulez.
acheminement des messages
Prenez votre événement et envoyez-le à un/plusieurs endpoint. Le routage peut être assez intelligent, le bus peut router le message en fonction du type de message, du contenu du message ou de tout autre critère. Le routage peut être intelligent et dynamique.
Transformation De Message
Transforme votre message dans un autre format, cela peut être aussi simple que de XML à JSON ou d'une ligne sur une table de base de données à une requête HTTP. La Transformation peut se produire dans les données elles-mêmes, par exemple l'échange de formats de date.
Enrichissement De Données
Ajoute ou modifie des données dans votre message en appelant les services en cours de route. Par exemple, si un le bus peut utiliser un service de recherche de code postal pour ajouter des données d'adresse.
..et beaucoup, beaucoup plus. Lorsque vous commencez à regarder dans les détails, vous pouvez vraiment commencer à voir pourquoi les gens utilisent ces choses.
parce qu'il peut être une étape importante dans la manière de découpler les modules d'application à une architecture basée sur le service .
ainsi, dans votre cas, si vous n'avez pas l'intention de découpler les modules de votre application en services isolés, alors la mise en œuvre native du Pattern D'Observateur en fera une solution plus simple.
mais si vous voulez construire disons un Micro-Services architecture l'event-bus permettra d'obtenir les avantages de ce style d'architecture afin que vous puissiez, par exemple, mettre à jour et déployer seulement une partie de votre application sans affecter les autres, parce qu'ils sont simplement connectés à travers l'event-bus.
donc la question principale ici est le niveau désiré de composantes de l'application découplant .
quelques références à ce sujet:
une bonne analogie est celle d'un central téléphonique, où chaque combiné peut composer avec tous les autres combinés. Un combiné compromis peut s'accorder avec d'autres conversations. Le contrôle de programme circule comme des fils (cyclomatic complexity anyone!) Ceci est similaire à l'exigence d'avoir une connexion/un support physique entre deux points terminaux. C'est le cas pour N combinés au lieu d'avoir des flux NC2 (logique combinatoire) pour chaque nouveau combiné, nous avons tendance à obtenir des flux N.
une réduction de la complexité implique un code facile à comprendre. Commençons par les points saillants que vous avez mis en évidence: 1. Connaissances mondiales 2. Modifications intrusives.
Global knowledge: Envisager de message d'événement soit une enveloppe. Du point de vue du gestionnaire d'événements/de l'expéditeur, il n'y a pas de données exposées, il s'agit de voir une enveloppe (à moins qu'une classe dérivée ne tente de faire une inspection en utilisant les vérifications "instanceof"). Dans une bonne conception OOP, cela ne se produirait jamais.
Intrusive modifications: au lieu d'avoir une approche d'auditeur spécifique à un événement, on peut utiliser une approche globale de gestion d'événement. En tant que tel, nous avons un type d'événement global (sur lequel les données sont inversées et dévalorisées). C'est un peu comme le modèle PropertyBeanSupport en Java. Avec un seul type d'événement, nous sommes tenus d'avoir un seul expéditeur et l'auditeur types. Cela implique que vous n'avez pas besoin de modifier le bus/listeners chaque fois que vous voyez quelque chose de nouveau. Le laid down-casting peut être adouci en utilisant le modèle D'Adaptateur (S'il vous plaît ne commencez pas que d'un autre niveau de la citation de redirection!). Les programmeurs peuvent écrire assemblée dans n'importe quelle langue. Le besoin de bon sens et d'intelligence ne peut donc pas être substitué. Tous j'ai l'intention de l'état est-il peut être un outil efficace.
les récepteurs d'événements réels peuvent utiliser les écouteurs (composition/proxy) facilement. Dans une telle base de code Java, les auditeurs ressembleraient à des déclarations de classe interne autonomes (avec des avertissements inutilisés étant signalés dans certains IDEs). C'est akeen à deux joueurs sur la plage jouant à un jeu de balle, les joueurs ne réagissent pas jusqu'à ce qu'ils voient la balle.
"@duffymo "souligne un autre aspect intéressant: "point D'échec unique". Cela pourrait en théorie affecter n'importe quel objet résidant en mémoire(RAM) et non spécifique aux MessageHandlers.
comme exemple pratique, la synchronisation de notre application avec un service web toutes les X minutes, et si de nouvelles données sont reçues, nous devons mettre à jour l'interface graphique. Maintenant, parce que le SyncAdapter tourne sur un thread d'arrière-plan, vous ne pouvez pas simplement pointer vers un textview et modifier ses propriétés, Vous devez bulle un événement. Et la seule façon de s'assurer que vous attrapez cet événement est si vous avez un objet partagé (statique,singleton) passant cet événement autour pour les abonnés à gérer.