Каковы хорошие примеры использования паттерна / идиомы CALLBACK? - PullRequest
2 голосов
/ 08 октября 2009

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

Ответы [ 5 ]

2 голосов
/ 08 октября 2009

Обратные вызовы на самом деле не являются «шаблоном» - они больше похожи на строительный блок. Ряд банд из четырех шаблонов проектирования используют виртуальные методы в стиле обратного вызова. Джастин Нисснер уже упомянул Наблюдатель .

Обратные вызовы намного старше, чем ООП (и, вероятно, старше, чем 3GL и даже на ассемблере). Другая старая идея - блок параметров - интерпретация C представляет собой структуру, полную связанных элементов, которые должны быть переданы в функцию, чтобы функция не нуждалась в огромном списке параметров.

Классы ООП основаны на блоке параметров (и добавляют к нему философию). Сам экземпляр класса является блоком параметров, передаваемым ссылкой на его методы. Виртуальная таблица - это блок параметров обработки отправки. Каждый виртуальный метод имеет указатель обратного вызова в блоке параметров диспетчеризации. Чистый виртуальный метод резервирует место для указателя обратного вызова в блоке параметров и обещает предоставить фактический указатель позже.

Поскольку класс является строительным блоком для объектно-ориентированных шаблонов проектирования, а блоки параметров и обратные вызовы являются строительными блоками классов - хорошо, вы можете утверждать, что все шаблоны проектирования ООП построены на основе этих идей.

Я бы хотел сказать «блоки параметров и обратные вызовы, а также правила стиля, определяющие их использование, вдохновленную ориентацию объекта», но, как бы это ни звучало привлекательно, я не знаю, правда ли это.

1 голос
/ 08 октября 2009

Я использую обратные вызовы почти каждый день в следующих сценариях:

  • События: Когда пользователь щелкает мышью по элементу управления, нажимает клавишу или иным образом взаимодействует с пользовательским интерфейсом так, как мне нужно, я подписываюсь на делегата, который элемент управления публикует для события. Затем я могу обработать его, обновив пользовательский интерфейс, отменив событие при определенных обстоятельствах или иным образом предприняв какое-либо специальное действие.

  • Многопоточное программирование: при программировании графического интерфейса важно поддерживать адаптивный интерфейс и сообщать пользователю о ходе длительного фонового события. Для этого я запускаю задачу в отдельном потоке и затем публикую делегаты (события в мире .NET), которые предоставляют моему пользовательскому интерфейсу возможность уведомлять пользователя о прогрессе, который происходит.

  • Лямбда-функции. В .NET лямбда-функции - это форма делегата, позволяющая мне взаимодействовать с другой частью кода в более поздний момент времени. LINQ является отличным примером этого. Я могу создать небольшую функцию сопоставления и затем предоставить ее для запроса LINQ. Позже, когда я выполняю свой запрос к коллекции, вызывается функция сопоставления, чтобы определить, есть ли совпадение для запроса. Это позволяет мне не создавать или беспокоиться о механизме запросов. Я просто должен сказать механизму запросов, куда идти, чтобы узнать, является ли сравнение совпадением.

Эти примеры просто царапают поверхность, я уверен. Но они являются полезными примерами того, как я использую обратные вызовы каждый день.

1 голос
/ 08 октября 2009

Платформа .NET активно использует обратные вызовы для реализации шаблона Observer.

Они также используются для обработки асинхронных процессов.

0 голосов
/ 08 октября 2009

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

Но в javascript, а теперь и в C # 3, я передаю функции в качестве параметра, чтобы обработка могла продолжаться без явной настройки делегата для вызова.

0 голосов
/ 08 октября 2009

Objective C и инфраструктура Какао широко используют его. Примером может быть NSURLConnection, который будет сообщать объект, данный ему (называемый делегатом ), когда что-то случится с соединением:

NSURLConnection *foo = [[NSURLConnection alloc] initWithRequest:request delegate:self];

Обратите внимание на прохождение delegate там. Запрос выполняется в фоновом режиме, а затем экземпляр отправляет делегату сообщения (в данном случае self), например:

connectionDidFinishLoading:
connection:didFailWithError:

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

.NET также имеет делегатов, которые похожи. Думай о событиях.

...