¿Cómo es el patrón de publicación-suscripción diferente de gotos?


11

Tengo entendido que las declaraciones de Goto generalmente están mal vistas . Pero el patrón de publicación-suscripción parece ser conceptualmente similar en el sentido de que cuando un código publica un mensaje, realiza una transferencia de control unidireccional. El programador puede no tener idea de qué partes del programa se están suscribiendo a este mensaje.

He visto algo similar en muchos programas de JavaScript en los que los eventos se utilizan para "saltar" convenientemente a través de los módulos. ¿Me estoy perdiendo algo sobre los patrones de publicación-suscripción o de eventos?


55
return, try/catch, break, continue, switch- esas son todas goto con diferentes niveles de restricción incorporada en Goto considera perjudicial es perjudicial para pensar acerca de cómo funciona el código..

@MichaelT: Para una abrumadora mayoría de los casos, existen alternativas al goto que facilitan razonar sobre el código. No hay daño en apreciar ese hecho. El daño se hace solo si no usa goto cuando está justificado (lo que generalmente no es así), o si lo usa descuidadamente. Creo que Apple nos mostró un buen ejemplo de esto último.
back2dos

... no tengo idea de qué partes del programa están suscribiendo ... : La primera gran diferencia con las gotomentiras en el s al final de las partes . La segunda gran diferencia radica en la idea . La tercera gran diferencia es que es conceptualmente a gosub, no a goto.
Mouviciel

1
Está más cerca del "venir de" de INTERCAL.
CodesInChaos

@ back2dos también es un buen ejemplo de por qué prefiero usar llaves incluso para bloques de código de 1 línea.
MetaFight

Respuestas:


19

Sí, definitivamente te estás perdiendo algo . Gotos normalmente se usaría, como dijiste, para realizar una transferencia de control unidireccional.

Sin embargo, los eventos no hacen eso. Cuando el código dispara el evento, sabe muy bien que una vez que se publica el evento (o se procesa, se pone en cola, se dispara ... etc.) la ejecución del código se reanudará en la línea siguiente del código que generó el evento.

El uso de goto crea un acoplamiento muy estrecho entre el código que llama a esa declaración y el código que está en el extremo receptor. El desarrollador debe tener un conocimiento íntimo de ambos lugares para poder usar goto.

Por otro lado, el código que dispara eventos generalmente no sabe o no le importa quién está interesado en escuchar ese evento. No podría ser un oyente. O podría haber 100 oyentes o 0. Esos oyentes podrían estar en el mismo programa donde se activó el evento, o podrían estar en una aplicación completamente diferente, o podrían estar en una máquina diferente. En lo que respecta al editor, tan pronto como genera el evento, su trabajo está hecho.

Si estás conmigo hasta ahora, lo que describí anteriormente es el caso ideal de patrón de pub / sub. Desafortunadamente, en el mundo real, las cosas no siempre son ideales y hay casos en los que los editores generan un evento, se invoca a un suscriptor, cambia un montón de estado y para cuando la ejecución del código vuelve al editor, "el mundo" parece tener sido puesto boca abajo. Y estoy seguro de que te has encontrado con esto en el pasado, porque esta condición a menudo surge cuando el patrón pub / sub se implementa de una manera muy simple (por ejemplo, mediante el uso de delegados o eventos en C #, o punteros de función / interfaz en C / C ++).

Pero este problema no es necesariamente un patrón pub / sub, sino más bien la implementación del mismo. Esta es la razón por la cual muchos sistemas dependen de las colas para que cuando se publique un evento, simplemente se ponga en cola para ser invocado más tarde, lo que le da al editor la oportunidad de finalizar la ejecución mientras el mundo aún está intacto. Cuando el editor termine de hacer su trabajo, un bucle de eventos (también conocido como bucle de despacho) mostrará los eventos e invocará a los suscriptores.


+1 publicar / suscribir permite acoplamiento flojo; goto no lo hace
Fuhrmanator

6

Hay un par de diferencias Primero, cuando un código ejecuta GOTO, cede el control y no hay garantía de que recupere el control. Sin embargo, un editor en pub / sub seguirá ejecutando y realizando su lógica, enviando mensajes según corresponda. Su comportamiento es comprensible y predecible.

En segundo lugar, el suscriptor recibirá mensajes y, a diferencia de GOTO, el mensaje en sí lleva contexto. Tanto el tipo de mensaje como las propiedades que posee ayudan a decirle al suscriptor que desempeñe su función. Y, después de manejar un mensaje, el suscriptor aún puede tomar nuevos mensajes. Por lo tanto, su comportamiento también es comprensible y predecible.

La gran diferencia es que el editor y el suscriptor tienen un flujo de ejecución bien definido y, en esencia, seguirán haciendo bucles y haciendo su trabajo, mientras envían y reciben mensajes. El código con GOTO puede estar bien escrito y ordenado, pero también puede degradarse y no existe la misma garantía de un comportamiento claramente entendido.

Tienes razón, sin embargo. Alguien podría escribir un sistema pub / subs con tantos mensajes y tantos pequeños saltos que hacer un seguimiento del flujo de procesamiento podría convertirse en una pesadilla. Y, por otro lado, podría escribir un sistema con GOTO que se comporte de manera extremadamente ordenada y se entienda fácilmente. (Estoy pensando en el código de ensamblaje para sistemas muy complejos antes de que los lenguajes simbólicos se hicieran cargo).

Pero, por lo general, el desacoplamiento que obtiene de pub / sub simplifica el problema del procesamiento distribuido y desacopla la lógica dentro de su sistema. También típicamente, los GOTO directos tienden a crear sistemas complicados donde la comprensión del flujo de control se vuelve problemática.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.