En quoi le modèle de publication-abonnement est-il différent de gotos?


11

Je crois comprendre que les déclarations Goto sont généralement mal vues . Mais le modèle de publication-abonnement semble être conceptuellement similaire en ce que lorsqu'un morceau de code publie un message, il effectue un transfert de contrôle à sens unique. Le programmeur peut n'avoir aucune idée des parties du programme qui s'abonnent à ce message.

J'ai vu quelque chose de similaire dans de nombreux programmes JavaScript dans lesquels les événements sont utilisés pour "sauter" facilement entre les modules. Suis-je en train de manquer quelque chose au sujet des modèles de publication-abonnement ou d'événement?


5
return, try/catch, break, continue, switch- ce sont tous goto à différents niveaux de restriction construit Goto considéré comme nocif est nuisible à la réflexion sur le fonctionnement du code..

@MichaelT: Pour une écrasante majorité des cas, il existe des alternatives à goto qui permettent de raisonner plus facilement sur le code. Il n'y a aucun mal à apprécier ce fait. Le mal n'est fait que si vous n'utilisez pas goto lorsque cela est justifié (ce qui n'est généralement pas le cas), ou si vous utilisez négligemment goto. Je crois qu'Apple nous a montré un bon exemple de ce dernier.
back2dos

... aucune idée des parties du programme qui s'abonnent ... : La première différence majeure avec gotoréside dans le s à la fin des parties . La deuxième différence majeure réside dans aucune idée . La troisième différence majeure est que c'est conceptuellement un gosub, pas un goto.
mouviciel

1
C'est plus proche du "come from" d'INTERCAL.
CodesInChaos

@ back2dos, c'est aussi un bon exemple de la raison pour laquelle je préfère utiliser des accolades, même pour des blocs de code d'une ligne.
MetaFight

Réponses:


19

Oui, il vous manque définitivement quelque chose . Gotos serait généralement utilisé, comme vous l'avez dit, pour effectuer un transfert de contrôle à sens unique.

Cependant, les événements ne font pas cela. Lorsque le code déclenche l'événement, il sait très bien qu'une fois l'événement publié (ou traité, mis en file d'attente, déclenché ... etc), l'exécution du code reprendra sur la ligne suivante du code qui a généré l'événement.

L'utilisation de goto crée un couplage très étroit entre le code qui appelle cette instruction et le code qui se trouve à l'extrémité de réception. Le développeur doit avoir une connaissance intime des deux endroits pour utiliser goto.

D'un autre côté, le code qui déclenche des événements ne sait généralement pas ou ne se soucie pas de qui souhaite écouter cet événement. Il pourrait y avoir un auditeur. Ou il pourrait y avoir 100 auditeurs ou 0. Ces auditeurs pourraient être dans le même programme où l'événement a été déclenché, ou ils pourraient être dans une application complètement différente, ou ils pourraient être sur une machine différente. Pour l'éditeur, dès qu'il génère l'événement, son travail est terminé.

Si vous êtes avec moi jusqu'à présent, ce que j'ai décrit ci-dessus est le cas idéal du modèle pub / sub. Malheureusement, dans le monde réel, les choses ne sont pas toujours idéales et il y a des cas où les éditeurs génèrent un événement, un abonné est invoqué, change tout un tas d'état et au moment où l'exécution du code temporel revient à l'éditeur "le monde" semble avoir été bouleversé. Et je suis sûr que vous avez rencontré cela dans le passé, car cette condition survient souvent lorsque le modèle pub / sub est implémenté de manière très simple (par exemple via l'utilisation de délégués ou d'événements en C #, ou de pointeurs de fonction / interface en C / C ++).

Mais ce problème n'est pas nécessairement le modèle pub / sub mais plutôt sa mise en œuvre. C'est pourquoi de nombreux systèmes s'appuient sur les files d'attente pour que lorsqu'un événement est publié, il soit simplement mis en file d'attente pour être invoqué plus tard, ce qui donne à l'éditeur une chance de terminer l'exécution alors que le monde est toujours intact. Lorsque l'éditeur a terminé son travail, une boucle d'événement (aka boucle de répartition) sautera les événements et invoquera des abonnés.


+1 publier / s'abonner permet un couplage lâche; goto ne fait pas
Fuhrmanator

6

Il y a quelques différences. Premièrement, lorsqu'un code exécute GOTO, il abandonne le contrôle et rien ne garantit qu'il reprendra le contrôle. Un éditeur dans pub / sub, cependant, continuera à fonctionner et à exécuter sa logique, en envoyant des messages le cas échéant. Son comportement est compréhensible et prévisible.

Deuxièmement, l'abonné recevra des messages, et contrairement à GOTO, le message lui-même porte le contexte. Le type de message et toutes les propriétés qu'il contient aident à dire à l'abonné de remplir son rôle. Et, après avoir traité un message, l'abonné est toujours en mesure de prendre de nouveaux messages. Son comportement est donc aussi compréhensible et prévisible.

La grande différence est que l'éditeur et l'abonné ont un flux d'exécution bien défini, et ils continueront, en substance, à boucler et à faire leur travail, tout en envoyant et en recevant des messages. Le code avec GOTO peut être bien écrit et ordonné, mais il peut également se dégrader, et il n'y a pas la même garantie d'un comportement clairement compris.

Vous avez raison cependant. Quelqu'un pourrait écrire un système pub / sub avec autant de messages et tant de petits sauts que garder une trace du flux de traitement pourrait devenir un cauchemar. Et d'autre part, vous pourriez écrire un système avec GOTO qui se comporte de manière extrêmement ordonnée et est facilement compréhensible. (Je pense au code assembleur pour les systèmes très complexes avant que les langages symboliques ne prennent le relais.)

Mais généralement, le découplage que vous gagnez de pub / sub simplifie le problème du traitement distribué et découplage la logique au sein de votre système. De manière typique, les GOTO simples ont tendance à créer des systèmes complexes où la compréhension du flux de contrôle devient problématique.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.