Чем шаблон публикации-подписки отличается от gotos?


11

Насколько я понимаю, заявления Гото, как правило, осуждаются . Но шаблон « публикация-подписка» концептуально похож на то, что, когда часть кода публикует сообщение, он выполняет одностороннюю передачу управления. Программист может не знать, какие части программы подписываются на это сообщение.

Я видел нечто подобное во многих программах на JavaScript, в которых события используются для удобного «перехода» между модулями. Я что-то упускаю из шаблонов публикации-подписки или событий?


5
return, try/catch, break, continue, switch- те все goto с различными уровнями ограничения , построенного в Гото считается вредным вредно думать о том , как работает код..

@MichaelT: В подавляющем большинстве случаев есть альтернативы goto, которые упрощают анализ кода. Там нет никакого вреда в оценке этого факта. Вред наносится только в том случае, если вы не используете goto, когда это оправдано (а обычно это не так), или если вы используете goto небрежно. Я считаю, что Apple показала нам хороший пример последнего.
back2dos

... не знаю , какие части программы подписываются ... : Первое основное отличие gotoзаключается в с в конце частей . Второе главное отличие заключается в том, что мы не знаем . Третье основное отличие состоит в том, что это концептуально а gosub, а не goto.
Мувичиэль

1
Это ближе к интеркалу "родом".
CodesInChaos

@ back2dos это также хороший пример того, почему я предпочитаю использовать фигурные скобки даже для однострочных блоков кода.
MetaFight

Ответы:


19

Да, вы определенно что-то упускаете . Как вы сказали, Gotos обычно используется для односторонней передачи управления.

Однако события этого не делают. Когда код запускает событие, он прекрасно знает, что как только событие будет опубликовано (или обработано, поставлено в очередь, запущено ... и т. Д.), Выполнение кода возобновится со следующей строки кода, сгенерировавшего событие.

Использование goto создает очень тесную связь между кодом, который вызывает этот оператор, и кодом, который находится на принимающей стороне. Разработчик должен иметь глубокие знания обоих мест, чтобы использовать goto.

С другой стороны, код, который запускает события, обычно не знает или не заботится о том, кто заинтересован в прослушивании этого события. Там может быть слушатель. Или может быть 100 слушателей или 0. Эти слушатели могут быть в той же программе, где было запущено событие, или они могут быть в совершенно другом приложении, или они могут быть на другой машине. Что касается издателя, как только он генерирует событие, его работа завершена.

Если вы до сих пор со мной, то, что я описал выше, является идеальным примером паттерна pub / sub. К сожалению, в реальном мире вещи не всегда идеальны, и есть случаи, когда издатели генерируют событие, подписчик вызывается, изменяет целый набор состояний и к тому времени, когда выполнение кода возвращается обратно к издателю, «мир», кажется, имеет был перевернут с ног на голову. И я уверен, что вы сталкивались с этим в прошлом, потому что это условие часто возникает, когда шаблон pub / sub реализуется очень простым способом (например, посредством использования делегатов или событий в C #, или указателей на функции / интерфейс в C / C ++).

Но эта проблема не обязательно шаблон паб / суб, а скорее ее реализация. Вот почему многие системы полагаются на очереди, поэтому, когда событие публикуется, оно просто ставится в очередь для последующего вызова, что дает издателю шанс завершить выполнение, пока мир еще не поврежден. Когда издатель выполнит свою работу, цикл событий (он же диспетчерский цикл) выскочит из событий и вызовет подписчиков.


+1 публикация / подписка позволяет свободную связь; Goto не
Fuhrmanator

6

Есть пара отличий. Во-первых, когда код выполняет GOTO, он отказывается от контроля, и нет никакой гарантии, что он восстановит контроль. Однако издатель в pub / sub будет продолжать работать и выполнять свою логику, отправляя сообщения соответствующим образом. Его поведение понятно и предсказуемо.

Во-вторых, подписчик будет получать сообщения, и в отличие от GOTO, само сообщение несет контекст. Как тип сообщения, так и любые свойства, которые оно несет, помогают подписчику выполнять свою роль. И, после обработки сообщения, подписчик все еще может принимать новые сообщения. Так что это поведение тоже понятно и предсказуемо.

Большая разница состоит в том, что издатель и подписчик имеют четко определенный поток выполнения, и они, по сути, будут продолжать циклы и выполнять свою работу, отправляя и получая сообщения. Код с GOTO может быть хорошо написан и упорядочен, но он также может ухудшаться, и нет такой же гарантии четко понятого поведения.

Вы правы, хотя. Кто-то может написать систему паб / подсистему с таким количеством сообщений и таким количеством маленьких скачков, что отслеживание потока обработки может стать кошмаром. А с другой стороны, вы могли бы написать систему с GOTO, которая ведет себя чрезвычайно упорядоченно и легко понятна. (Я имею в виду ассемблерный код для очень сложных систем, прежде чем символические языки вступили во владение.)

Но обычно развязка, которую вы получаете от pub / sub, упрощает проблему распределенной обработки и разъединяет логику в вашей системе. Также обычно прямые GOTO имеют тенденцию создавать сложные системы, где понимание потока управления становится проблематичным.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.