Чим відрізняється модель публікації-підписки від gotos?


11

Я розумію, що твердження Гото, як правило, нахмурені . Але модель публікації-підписки, схоже, концептуально схожа на те, що коли фрагмент коду публікує повідомлення, він здійснює односторонню передачу контролю. Програміст може не знати, які частини програми підписуються на це повідомлення.

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


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

@MichaelT: У переважній більшості випадків є альтернативи goto, які полегшують міркування про код. Немає шкоди в оцінці цього факту. Шкода робиться лише в тому випадку, якщо ви не використовуєте Goto, коли це гарантовано (як правило, це не так), або якщо ви використовуєте goto необережно. Я вважаю, що Apple показала нам хороший приклад останнього.
back2dos

... не маю уявлення, які частини програми підписуються ... : Перша основна відмінність gotoполягає в тому, що в кінці частин . Друга основна відмінність полягає не в ідеї . Третя основна відмінність полягає в тому, що це концептуально а gosub, а не а goto.
mouviciel

1
Це ближче до "родом" від INTERCAL.
CodesInChaos

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

Відповіді:


19

Так, вам точно щось не вистачає . Готос зазвичай використовувався, як ви сказали, для здійснення однобічної передачі управління.

Однак події цього не роблять. Коли код запускає подію, він добре знає, що після події буде опубліковано (або оброблено, у черзі, запустито ... тощо) виконання коду відновиться в наступному рядку в коді, який генерував подію.

Використання goto створює дуже тісний зв'язок між кодом, який викликає цей вислів, і кодом, що знаходиться на кінці прийому. Розробник повинен мати глибокі знання про обидва місця, щоб використовувати goto.

З іншого боку, код, який викликає події, зазвичай не знає і не цікавить, хто зацікавлений слухати цю подію. Тут міг бути слухач. Або може бути 100 слухачів, або 0. Ці слухачі можуть бути в тій же програмі, де розгорнута подія, або вони можуть бути в зовсім іншій програмі, або вони можуть бути на іншій машині. Що стосується видавця, як тільки він генерує подію, його робота виконана.

Якщо ви зараз зі мною, то, що я описав вище, ідеальний випадок паб / підрозділу. На жаль, у реальному світі речі не завжди ідеальні, і бувають випадки, коли видавці генерують подію, абонент отримує виклик, змінює цілу купу штатів і до моменту виконання коду повертається назад до видавця, "видається, що світ" були перевернуті догори дном. І я впевнений, що раніше ви стикалися з цим, оскільки ця умова часто виникає, коли шаблон pub / sub реалізується дуже просто (наприклад, за допомогою використання делегатів або подій у C # або покажчиків функцій / інтерфейсів у C / C ++).

Але ця проблема не обов'язково має шаблон паб / під, а скоріше її реалізацію. Ось чому багато систем покладаються на черги, так що коли опублікована подія, її просто в черзі викликати пізніше, що дає видавцеві можливість закінчити виконання, поки світ ще недоторканий. Коли видавець зробить це своєю роботою, цикл подій (він же цикл відправлення) спливе події та викликатиме передплатників.


+1 опублікувати / підписатися дозволяє вільне з'єднання; goto doesn’t
Fuhrmanator

6

Існує пара відмінностей. По-перше, коли код виконує GOTO, він відмовляється від контролю, і немає гарантії, що він відновить контроль. Видавець у pub / sub, однак, буде продовжувати працювати та виконувати свою логіку, надсилаючи повідомлення відповідно. Його поведінка зрозуміла і передбачувана.

По-друге, абонент отримуватиме повідомлення, і на відміну від GOTO, саме повідомлення містить контекст. Як тип повідомлення, так і будь-які властивості, які він несе, допомагають сповістити абонента виконувати свою роль. І після обробки повідомлення абонент все ще може приймати нові повідомлення. Тож його поведінка теж зрозуміла і передбачувана.

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

Ти прав, правда. Хтось міг написати паб / підсистему з такою кількістю повідомлень і такою кількістю маленьких стрибків, що відстеження потоку обробки може стати кошмаром. А з іншого боку, ви можете написати систему з GOTOs, яка веде себе надзвичайно впорядковано і легко зрозуміла. (Я думаю про код складання для дуже складних систем до того, як символічні мови перейдуть на озброєння.)

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.