Qual a diferença entre o padrão de publicação e assinatura e o gotos?


11

Meu entendimento é que as declarações Goto geralmente são desaprovadas . Mas o padrão de publicação-assinatura parece ser conceitualmente semelhante, pois quando um trecho de código publica uma mensagem, ele realiza uma transferência de controle unidirecional. O programador pode não ter idéia de quais partes do programa estão assinando esta mensagem.

Eu vi algo semelhante em muitos programas JavaScript nos quais os eventos são usados ​​para "saltar" convenientemente entre os módulos. Estou perdendo alguma coisa sobre os padrões de publicação-assinatura ou orientado a eventos?


5
return, try/catch, break, continue, switch- esses são todos goto com vários níveis de restrição construído em Goto considerado prejudicial é prejudicial para pensar sobre como o código funciona..

@ MichaelT: Para a esmagadora maioria dos casos, existem alternativas para irmos que facilitam o raciocínio sobre o código. Não há mal nenhum em apreciar esse fato. O dano é feito apenas se você não usar o goto quando garantido (o que geralmente não é), ou se você usar o goto descuidadamente. Acredito que a Apple nos mostrou um bom exemplo deste último.
mar2

... não faço ideia de que partes do programa estão se inscrevendo ... : A primeira grande diferença gotoestá no s no final das partes . A segunda grande diferença não tem idéia . A terceira grande diferença é que é conceitualmente a gosub, não a goto.
Mouviciel

1
Está mais próximo do "venha de" da INTERCAL.
precisa saber é o seguinte

@ back2dos também é um bom exemplo de por que prefiro usar chaves, mesmo para blocos de código de 1 linha.
MetaFight

Respostas:


19

Sim, você definitivamente está perdendo alguma coisa . O Gotos normalmente seria usado, como você disse, para realizar uma transferência de controle unidirecional.

No entanto, eventos não fazem isso. Quando o código aciona o evento, ele sabe muito bem que, uma vez que o evento seja publicado (ou processado, enfileirado, acionado ... etc), a execução do código será retomada na linha seguinte do código que gerou o evento.

O uso de goto cria um acoplamento muito estreito entre o código que chama essa declaração e o código que está no lado receptor. O desenvolvedor precisa ter um conhecimento íntimo dos dois lugares para usar o goto.

Por outro lado, o código que aciona eventos normalmente não sabe nem se importa com quem está interessado em ouvir esse evento. Não poderia ser um ouvinte. Ou pode haver 100 ouvintes ou 0. Esses ouvintes podem estar no mesmo programa em que o evento foi acionado, ou podem estar em um aplicativo completamente diferente ou em uma máquina diferente. No que diz respeito ao editor, assim que ele gera o evento, seu trabalho é concluído.

Se você está comigo até agora, o que descrevi acima é o caso ideal de padrão pub / sub. Infelizmente, no mundo real, as coisas nem sempre são ideais e há casos em que os editores geram um evento, um assinante é chamado, muda todo um estado e, quando a execução do código retorna ao editor, "o mundo" parece ter foi virado de cabeça para baixo. E tenho certeza de que você já se deparou com isso no passado, porque essa condição geralmente surge quando o padrão pub / sub é implementado de uma maneira muito simples (por exemplo, através do uso de delegados ou eventos em C #, ou ponteiros de função / interface em C / C ++).

Mas esse problema não é necessariamente o padrão pub / sub, mas a implementação. É por isso que muitos sistemas dependem de filas para que, quando um evento for publicado, ele simplesmente seja enfileirado para ser chamado posteriormente, dando ao editor a chance de concluir a execução enquanto o mundo ainda está intacto. Quando o editor terminar o trabalho, um loop de evento (também conhecido como loop de expedição) sairá dos eventos e chamará os assinantes.


+1 publicar / assinar permite um acoplamento flexível; goto does not
Fuhrmanator

6

Existem algumas diferenças. Primeiro, quando um código executa o GOTO, ele desiste do controle e não há garantia de que recuperará o controle. Um editor em pub / sub, no entanto, continuará executando e executando sua lógica, enviando mensagens conforme apropriado. Seu comportamento é compreensível e previsível.

Em segundo lugar, o assinante receberá mensagens e, diferentemente do GOTO, a própria mensagem carrega contexto. O tipo de mensagem e todas as propriedades que ela carrega ajudam a informar o assinante a desempenhar sua função. E, depois de manipular uma mensagem, o assinante ainda pode receber novas mensagens. Portanto, seu comportamento também é compreensível e previsível.

A grande diferença é que o publicador e o assinante têm um fluxo de execução bem definido e, em essência, continuarão repetindo e executando suas tarefas, enquanto enviam e recebem mensagens. O código com GOTOs pode ser bem escrito e ordenado, mas também pode se degradar, e não há a mesma garantia de comportamento claramente entendido.

Você está certo, no entanto. Alguém poderia escrever um pub / subsistema com tantas mensagens e tantos saltos que acompanhar o fluxo do processamento poderia se tornar um pesadelo. Por outro lado, você pode escrever um sistema com GOTOs que se comporte de maneira extremamente ordenada e seja facilmente compreendido. (Estou pensando no código de montagem para sistemas muito complexos antes de as linguagens simbólicas assumirem o controle.)

Porém, normalmente, a dissociação que você obtém de pub / sub simplifica o problema do processamento distribuído e a lógica de dissociação em seu sistema. Também normalmente, os GOTOs diretos tendem a criar sistemas complicados, onde a compreensão do fluxo de controle se torna problemática.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.