Прослушивание доктрины и подписчика

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

Ответ 1

С моей точки зрения, существует только одно существенное различие:

  • Подписывается прослушиватель с указанием событий, на которых он слушает.
  • У Абонента есть способ сообщить диспетчеру, какие события он слушает

Это может показаться большой разницей, но если вы думаете об этом, есть некоторые случаи, когда вы хотите использовать один над другим:

  • Вы можете назначить одного слушателя многим диспетчерам с разными событиями, так как они установлены во время регистрации. Вам нужно только убедиться, что каждый метод установлен в слушателе.
  • Вы можете изменить события, на которых зарегистрирован подписчик во время выполнения, и даже после регистрации подписчика, изменив возвращаемое значение getSubscribedEvents (подумайте о времени, когда вы слушаете очень шумное событие, и вы хотите только выполнить что-то один раз)

Могут быть и другие различия, о которых я не знаю!

Ответ 2

Не знаю, сделано ли это случайно или намеренно. Но у подписчиков более высокий приоритет, чем у слушателей - https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php#L73-L98

С доктрины, все равно, что это (слушатель или подписчик), в конце концов оба зарегистрированы в качестве слушателей - https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/EventManager.php#L137-L140

Это то, что я заметил.

Ответ 3

Вы должны использовать подписчик событий, если хотите иметь дело с несколькими событиями в одном классе, например, в этой странице статьи symfony2 doc, можно обратите внимание, что прослушиватель событий может управлять только одним событием, но позволяет сказать, что вы хотите иметь дело с несколькими событиями для одного объекта, prePersist, preUpdate, postPersist и т.д.... если вы используете прослушиватель событий, вам придется закодировать несколько прослушивателей событий, по одному для каждого событие, но если вы отправитесь с подписчиком событий, вам просто нужно закодировать один класс на подозрительном событии, посмотрите, что с подписчиком событий вы можете управлять несколькими событиями в одном классе, ну, вот как я его использую, я предпочитаю сфокусировать код в чем нуждается модельный бизнес, одним из примеров этого может быть то, что вы хотите обработать несколько событий жизненного цикла globaly только для группы ваших сущностей, чтобы сделать это, вы можете закодировать родительский класс и определить эти глобальные методы в нем, а затем сделать свой объекты наследуют этот класс, а позже в вашем случае susbcriber подписывается каждый канун nt вы хотите, prePersist, preUpdate, postPersist и т.д., а затем попросите этот родительский класс и выполните эти глобальные методы.

Ответ 4

Оба позволяют выполнить что-то на конкретном событии pre/post persist и т.д.

Однако слушатели только позволяют выполнять поведение, инкапсулированное внутри вашего объекта. Таким образом, пример может обновлять отметку с отметкой "date_edited".

Если вам нужно выйти за пределы вашего объекта, вам понадобится подписчик. Хорошим примером может быть вызов внешнего API, или если вам нужно использовать/проверять данные, не связанные напрямую с вашим объектом.

Ответ 5

Еще одна важная вещь: Doctrine EventSubscribers не позволяют вам устанавливать приоритет.

Подробнее об этом выпуске здесь