webentwicklung-frage-antwort-db.com.de

Doktrin-Hörer gegen Abonnent

Ich arbeite im Symfony2-Framework und frage mich, wann man einen Doctrine-Abonnenten gegenüber einem Hörer verwenden würde. Doctrines Dokumentation für Hörer ist sehr klar, jedoch sind die Abonnenten eher beschönigt. Der cookbook-Eintrag von Symfony ist ähnlich.

69
nurikabe

Aus meiner Sicht gibt es nur einen wesentlichen Unterschied:

  • Der Listener ist angemeldet und gibt die Ereignisse an, auf die er hört.
  • Der Abonnent verfügt über eine Methode, die dem Dispatcher mitteilt, welche Ereignisse er hört

Dies scheint kein großer Unterschied zu sein, aber wenn Sie darüber nachdenken, gibt es einige Fälle, in denen Sie eines über dem anderen verwenden möchten:

  • Sie können einen Listener vielen Dispatchern mit unterschiedlichen Ereignissen zuweisen, da diese zum Zeitpunkt der Registrierung festgelegt werden. Sie müssen lediglich sicherstellen, dass jede Methode im Listener vorhanden ist
  • Sie können die Ereignisse, für die ein Abonnent zur Laufzeit registriert ist, und auch nach der Registrierung des Abonnenten ändern, indem Sie den Rückgabewert von getSubscribedEvents ändern.

Es kann andere Unterschiede geben, die mir nicht bewusst sind!

82
Sgoettschkes

Ich weiß nicht, ob es versehentlich oder absichtlich geschieht. Aber Abonnenten haben eine höhere Priorität als Hörer - https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass /RegisterEventListenersAndSubscribersPass.php#L73-L98

Von der Doktrin her ist es egal, um was es sich handelt (Listener oder Subscriber), beide sind schließlich als Listener registriert - https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/EventManager .php # L137-L140

Das habe ich gesehen.

8

Sie sollten den Ereignisabonnenten verwenden, wenn Sie mit mehreren Ereignissen in einer Klasse umgehen möchten, z. B. in diesem symfony2-Dokumentseitenartikel . Möglicherweise stellen Sie fest, dass der Ereignis-Listener nur ein Ereignis verwalten kann Mehrere Ereignisse für eine Entität, PrePersist, PreUpdate, PostPersist usw. Wenn Sie den Ereignis-Listener verwenden, müssten Sie mehrere Ereignis-Listener codieren, einen für jedes Ereignis. Wenn Sie jedoch mit Ereignis-Abonnenten arbeiten, müssen Sie nur eine Klasse für das Ereignis codieren Susbcriber, sehen Sie, dass Sie mit dem Ereignisabonnenten mehr als ein Ereignis in einer Klasse verwalten können. Nun, so benutze ich es. Ich bevorzuge Code, der sich auf die Anforderungen des Modellgeschäfts konzentriert. Ein Beispiel dafür könnte die Bearbeitung sein Mehrere globale Lifecycle-Ereignisse nur für eine Gruppe von Entitäten. Um dies zu tun, können Sie eine übergeordnete Klasse codieren und diese globalen Methoden definieren. Anschließend können Sie die Entität erben, und später in Ihrem Ereignis unterschreiben Sie jedes Ereignis, das Sie möchten, prePersist preUpdat e, postPersist etc ... und fragen Sie dann nach dieser übergeordneten Klasse und führen Sie diese globalen Methoden aus. 

7
metalvarez

Eine weitere wichtige Sache: Doctrine EventSubscribers erlauben keine Prioritätensetzung.

Lesen Sie mehr zu diesem Thema hier

3
Wilt

Mit beiden können Sie etwas zu einem bestimmten Ereignis vor/nach dem Persist usw. ausführen.

Mit Listenern können Sie jedoch nur Verhaltensweisen ausführen, die in Ihrer Entität eingeschlossen sind. Ein Beispiel könnte das Aktualisieren eines Zeitstempels "date_edited" sein.

Wenn Sie den Kontext Ihrer Entität verlassen müssen, benötigen Sie einen Abonnenten. Ein gutes Beispiel ist der Aufruf einer externen API oder wenn Sie Daten verwenden/prüfen müssen, die nicht direkt mit Ihrer Entität zusammenhängen.

3
Lee Davis

Das sagt der Doc in 4.1. Da dies global auf Ereignisse angewendet wird, nehme ich an, dass es auch für Doctrine gilt (nicht 100% sicher).

Hörer oder Abonnenten

Listener und Abonnenten können in derselben Anwendung undeutlich verwendet werden. Die Entscheidung, eines von beiden zu verwenden, ist in der Regel eine Angelegenheit vom persönlichen Geschmack. Es gibt jedoch einige kleinere Vorteile für jeden von ihnen:

  • Abonnenten können einfacher wiederverwendet werden, da das Wissen über die Ereignisse in der Klasse und nicht in der Servicedefinition gespeichert wird. Das ist der Grund, warum Symfony Abonnenten intern verwendet;
  • Listener sind flexibler, da Bündel abhängig von einem bestimmten Konfigurationswert jedes davon bedingt aktivieren oder deaktivieren können.

http://symfony.com/doc/master/event_dispatcher.html#listeners-or-subscribers

2
Kaizoku Gambare

Aus der Dokumentation: 

Die gebräuchlichste Methode, ein Ereignis anzuhören, ist das Registrieren eines Ereignisses Zuhörer mit dem Dispatcher. Dieser Listener kann ein oder mehrere .__ anhören. Ereignisse und wird jedes Mal benachrichtigt, wenn diese Ereignisse ausgelöst werden.

Ereignisse können auch über einen Ereignisabonnenten abgehört werden. Ein Event Subscriber ist eine PHP Klasse, die dem Dispatcher genau sagen kann welche Ereignisse es abonnieren soll. Es implementiert das EventSubscriberInterface-Schnittstelle, für die eine einzige statische .__ erforderlich ist. Methode namens getSubscribedEvents ().

Siehe das Beispiel hier: 

https://symfony.com/doc/3.3/components/event_dispatcher.html