In che modo il modello di pubblicazione e sottoscrizione differisce dalle foto?


11

La mia comprensione è che le dichiarazioni Goto sono generalmente disapprovate . Ma il modello di pubblicazione-sottoscrizione sembra essere concettualmente simile in quanto quando un pezzo di codice pubblica un messaggio, esegue un trasferimento di controllo unidirezionale. Il programmatore potrebbe non avere idea di quali parti del programma si stanno iscrivendo a questo messaggio.

Ho visto qualcosa di simile in molti programmi JavaScript in cui gli eventi vengono utilizzati per "saltare" comodamente tra i moduli. Mi sto perdendo qualcosa riguardo ai pattern di pubblicazione-iscrizione o event-driven?


5
return, try/catch, break, continue, switch- queste sono tutte goto con vari livelli di restrizione costruito in Goto considerato nocivo è dannoso per pensare a come le opere di codice..

@MichaelT: per la stragrande maggioranza dei casi, ci sono alternative a goto che rendono più facile ragionare sul codice. Non c'è nulla di male nell'apprezzare questo fatto. Il danno viene fatto solo se non si usa goto se garantito (cosa che di solito non lo è) o se si usa goto con noncuranza. Credo che Apple ci abbia mostrato un buon esempio di quest'ultimo.
back2dos

... non ho idea di quali parti del programma si stiano iscrivendo ... : la prima grande differenza gotosta nella s alla fine delle parti . La seconda grande differenza non sta nell'idea . La terza differenza principale è che concettualmente è un gosub, non un goto.
mouviciel,

1
È più vicino al "vieni" di INTERCAL.
Codici A Caos

@ back2dos è anche un buon esempio del perché preferisco usare parentesi graffe anche per blocchi di codice a 1 riga.
MetaFight

Risposte:


19

Sì, sicuramente ti stai perdendo qualcosa . In genere, i goto vengono utilizzati, come hai detto, per eseguire un trasferimento di controllo unidirezionale.

Tuttavia, gli eventi non lo fanno. Quando il codice genera l'evento, sa perfettamente che una volta che l'evento viene pubblicato (o elaborato, messo in coda, attivato ... ecc.) L'esecuzione del codice riprenderà sulla riga successiva del codice che ha generato l'evento.

L'uso di goto crea un accoppiamento molto stretto tra il codice che chiama quell'istruzione e il codice che si trova sull'estremità ricevente. Lo sviluppatore deve avere una conoscenza intima di entrambi i luoghi per poter usare goto.

D'altra parte, il codice che genera eventi in genere non conoscerebbe o preoccuperebbe chi è interessato ad ascoltare l'evento. Ci potrebbe essere un ascoltatore. Oppure potrebbero esserci 100 ascoltatori o 0. Questi ascoltatori potrebbero essere nello stesso programma in cui è stato generato l'evento, oppure potrebbero trovarsi in un'applicazione completamente diversa o potrebbero trovarsi su una macchina diversa. Per quanto riguarda l'editore, non appena genera l'evento, il suo lavoro è terminato.

Se sei con me finora, quello che ho descritto sopra è il caso ideale di pub / sottotitoli. Sfortunatamente nel mondo reale le cose non sono sempre ideali e ci sono casi in cui gli editori generano un evento, un abbonato viene invocato, cambia un sacco di stati e quando l'esecuzione del codice temporale ritorna all'editore "il mondo" sembra avere stato capovolto. E sono sicuro che ti sei imbattuto in questo in passato, perché questa condizione si presenta spesso quando il modello pub / sub viene implementato in un modo molto semplice (ad esempio tramite l'uso di delegati o eventi in C # o puntatori di funzione / interfaccia in C / C ++).

Ma questo problema non è necessariamente pub / sub pattern ma piuttosto la sua implementazione. Questo è il motivo per cui molti sistemi si basano su code in modo che quando un evento viene pubblicato, viene semplicemente messo in coda per essere richiamato in seguito, dando all'editore la possibilità di terminare l'esecuzione mentre il mondo è ancora intatto. Quando l'editore ha finito di farlo, un ciclo di eventi (noto anche come ciclo di invio) farà scattare gli eventi e invocherà gli abbonati.


+1 pubblicazione / sottoscrizione consente un accoppiamento libero goto no
Fuhrmanator

6

Ci sono un paio di differenze. In primo luogo, quando un codice esegue GOTO, questo dà il controllo e non vi è alcuna garanzia che riprenderà il controllo. Un editore in pub / sub, tuttavia, continuerà a funzionare e ad eseguire la sua logica, inviando messaggi come appropriato. Il suo comportamento è comprensibile e prevedibile.

In secondo luogo, l'abbonato riceverà messaggi e, diversamente da GOTO, il messaggio stesso ha un contesto. Sia il tipo di messaggio, sia le proprietà che trasporta, aiutano a dire al sottoscrittore di svolgere il suo ruolo. E, dopo aver gestito un messaggio, l'abbonato è ancora in grado di prendere nuovi messaggi. Quindi anche il suo comportamento è comprensibile e prevedibile.

La grande differenza è che l'editore e l'abbonato hanno un flusso di esecuzione ben definito e, in sostanza, continueranno a girare e svolgere il proprio lavoro, mentre inviano e ricevono messaggi. Il codice con GOTO può essere ben scritto e ordinato, ma può anche degradare e non esiste la stessa garanzia di un comportamento chiaramente compreso.

Hai ragione, però. Qualcuno potrebbe scrivere un pub / sottosistema con così tanti messaggi e così tanti piccoli salti che tenere traccia del flusso di elaborazione potrebbe diventare un incubo. E d'altra parte, potresti scrivere un sistema con GOTO che si comporta in modo estremamente ordinato ed è facilmente comprensibile. (Sto pensando al codice assembly per sistemi molto complessi prima che i linguaggi simbolici prendessero il sopravvento.)

Ma in genere, il disaccoppiamento ottenuto da pub / sub semplifica il problema dell'elaborazione distribuita e disaccoppia la logica all'interno del sistema. Inoltre, in genere, i GOTO semplici tendono a creare sistemi complicati in cui la comprensione del flusso di controllo diventa problematica.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.