В шаблоне делегата только один объект может напрямую прослушивать события другого объекта. В шаблоне наблюдателя любое количество объектов может прослушивать события конкретного объекта. При разработке класса, который должен уведомлять другие объекты о событиях, зачем вам использовать шаблон делегата поверх шаблона наблюдателя? Я вижу модель наблюдателя как более гибкую. Сейчас у вас может быть только один наблюдатель, но для будущего проекта может потребоваться несколько наблюдателей.
9
Ответы:
Сам по себе шаблон делегата отсутствует. Я собираюсь предположить, что вы имеете в виду шаблон делегирования .
Насколько я понимаю, они полностью противоположны друг другу и используются для разных целей.
Как правило, с помощью шаблона наблюдателя любое количество объектов-наблюдателей будет прослушивать событие второго объекта и воздействовать на него. Второй объект не знает своих слушателей. Это просто призывает их.
Объект делегата передается второму объекту, который вызывает методы непосредственно в делегате. И в этом заключается преимущество, которое вы ищете. Вместо того, чтобы отправлять одно сообщение нескольким слушателям, он имеет полный контроль над одним объектом (в определенный момент времени). Смотрите также Инверсия Контроля .
источник
Вы смотрите на вещи неправильно. Наблюдатель видит, что происходит определенное событие. Это не влияет на это, или не владеет им. Делегат обрабатывает определенное событие и владеет обработчиком, даже если делегат владеет интерфейсом к событию.
источник
Это вопрос нескольких компромиссов.
Компромиссы:
Шаблон делегата:
Шаблон наблюдателя:
источник
Шаблон делегата, насколько я понимаю, известен как механизм обработки событий в других языках, например Delphi. Как таковая, это просто реализация шаблона наблюдателя с основным ограничением: только один слушатель за раз.
Недостаток обработчиков событий или делегатов очевиден: только один наблюдатель.
Преимущество не так очевидно: производительность. С шаблоном наблюдателя вы можете добавить много наблюдателей. Когда происходит событие, о котором необходимо уведомить наблюдателей, вам нужно будет перечислить наблюдателей и отправить каждому уведомление. Это может быстро застопорить любой наблюдаемый экземпляр, особенно если число событий, требующих уведомления, также значительно.
источник
int (*my_int_f)(int)
в C). Я всегда думал, что они могли бы сделать это проще для понимания, сделав его более похожим на struct / enum. Событие - это ловушка для гибкого массива слушателей, использующего одну подпись делегата. Вы могли бы сделать это без события (именно поэтому я предполагаю, что OP означало паттерн делегирования, который сильно отличается), но язык делает его проще для вас.Это старая статья, но я все равно буду ей звонить, потому что другие ответы не имеют отношения к тому, что происходит при использовании любого из паттернов, они скорее касаются теории, чем практики.
Как работают делегация и наблюдатель
С делегированием делегат точно выбирает, кто будет отвечать на конкретное событие в момент создания источника потенциального события. Вы можете думать об этом слушателе как о едином наблюдателе . В случае паттерна Observer наблюдатель выбирает, кого он наблюдает, когда ему это нравится; таким образом, зависимости обращаются, когда дело доходит до наблюдателя против делегирования. С моделью наблюдателя думайте о газете и подписчиках как о наблюдателях. Наблюдатели контролируют, когда создаются отношения. С делегацией подумайте о работнике и работодателе. Работодатель контролирует, когда создаются отношения и кто конкретно отвечает за конкретные события. Сотрудники не могут выбирать, над какими задачами они работают ... в общем.
Некоторые утверждают, что делегирование может иметь одного наблюдателя, но я думаю, что реальная разница между ними заключается в том, как назначается обработка событий. Вы никогда не увидите регистрацию делегата на событие. Он никогда не узнает, обрабатывает ли оно событие, пока оно не произойдет, и делегат не вызовет для него открытый метод.
Преимущество делегирования
Эта модель очень жесткая, а с большинством правильных конструкций она более простая и в целом более надежная. Это заставляет вас заранее объявить обработчик события во время инициализации источника потенциального события. Если вам нужен кто-то, чтобы направлять трафик, вы назначаете директора по трафику, прежде чем открыть улицу. В случае наблюдателя вы могли бы позволить гаишнику выбирать, когда направлять трафик в любое время, когда он или она захотят этого.
Недостаток делегирования
Недостаток этого дизайна в том, что он не гибкий. Если бы вы внедрили какой-то код для подписки на газету, газете / делегату пришлось бы точно определить, кто может читать новостные сюжеты в момент их создания. По схеме наблюдателя они могут быть зарегистрированы позже в любое время, и газете нужно будет только знать, что новый человек зарегистрировался.
Когда выбрать делегацию?
Если вам нужен один конкретный (ые) наблюдатель (и), и у вас нет причин для изменения того, кто наблюдает, тогда будет полезен жесткий дизайн схемы делегирования.
Например, вам нужен класс / объект для обработки всплывающих окон для конкретной ошибки. Существует не так много причин, почему во время выполнения вам нужно было бы переключаться между тем, кто обрабатывает конкретную ошибку, поэтому имеет смысл делегировать ошибку «Недостаточно памяти» одному объекту. Создание массива потенциальных обработчиков и последующая регистрация этих обработчиков для ошибки «Недостаточно памяти» не имеет большого смысла; это было бы примером использования модели наблюдателя в этой ситуации. Во время выполнения вы можете захотеть изменить то, какие методы вызываются или какой «делегат» вызывается для переменных событий, но выгрузка обработчика события для определенного события во время выполнения не является нормальной.
Нельзя поменять местами делегатов, как в случае с наблюдателем, это просто сложно. В реальном мире, возможно, вы хотите поменять гаишников, чтобы новый делегат обрабатывал трафик. Можно утверждать, что лучший дизайн позволил бы сделать оригинального делегата полицейским участком, а не одного полицейского, но я отвлекся ...
источник