Unterschied zwischen Observer, Pub / Sub und Datenbindung

161

Was ist der Unterschied zwischen dem Beobachtermuster , dem Veröffentlichen / Abonnieren und der Datenbindung ?

Ich habe ein bisschen nach Stack Overflow gesucht und keine guten Antworten gefunden.

Ich bin zu der Überzeugung gelangt, dass die Datenbindung ein Oberbegriff ist und es verschiedene Möglichkeiten gibt, sie zu implementieren, z. B. das Observer-Muster oder das Pub / Sub-Muster. Mit dem Beobachtermuster aktualisiert ein Observable seine Beobachter. Mit Pub / Sub können 0 viele Publisher Nachrichten bestimmter Klassen veröffentlichen und 0 viele Abonnenten können Nachrichten bestimmter Klassen abonnieren.

Gibt es andere Muster für die Implementierung der "Datenbindung"?

Jess
quelle
Ich habe eine andere gefunden: Dirty Checking , was Angular.js macht. Weitere Infos hier: stackoverflow.com/questions/9682092/databinding-in-angularjs
Jess

Antworten:

142

Hier ist meine Einstellung zu den drei:

Datenbindung

Im Kern bedeutet dies im Wesentlichen nur, dass "der Wert der Eigenschaft X für Objekt Y semantisch an den Wert von Eigenschaft A für Objekt B gebunden ist. Es werden keine Annahmen darüber getroffen, wie Y Änderungen an Objekt B kennt oder eingespeist wird.

Beobachter oder Observable / Observer

Ein Entwurfsmuster, mit dem ein Objekt die Fähigkeit besitzt, andere über bestimmte Ereignisse zu informieren - normalerweise mithilfe tatsächlicher Ereignisse, die wie Schlitze im Objekt mit der Form einer bestimmten Funktion / Methode aussehen. Das Observable ist derjenige, der Benachrichtigungen bereitstellt, und der Beobachter erhält diese Benachrichtigungen. In .net kann das Observable ein Ereignis verfügbar machen, und der Beobachter abonniert dieses Ereignis mit einem Haken in Form eines "Event-Handlers". Es werden keine Annahmen über den spezifischen Mechanismus getroffen, bei dem Benachrichtigungen auftreten, noch über die Anzahl der Beobachter, die ein Beobachter benachrichtigen kann.

Pub / Sub

Ein anderer Name (möglicherweise mit mehr "Broadcast" -Semantik) des Observable / Observer-Musters, der normalerweise einen "dynamischeren" Geschmack impliziert - Beobachter können Benachrichtigungen abonnieren oder abbestellen, und ein Observable kann mehrere Beobachter "anschreien". In .NET können hierfür die Standardereignisse verwendet werden, da Ereignisse eine Form von MulticastDelegate sind und somit die Übermittlung von Ereignissen an mehrere Abonnenten sowie die Abmeldung unterstützen können. Pub / Sub hat in bestimmten Kontexten eine etwas andere Bedeutung und beinhaltet normalerweise mehr "Anonymität" zwischen Ereignis und Eventer, was durch eine beliebige Anzahl von Abstraktionen erleichtert werden kann, wobei normalerweise ein "Mittlerer Mann" (wie eine Nachrichtenwarteschlange) involviert ist, der alles weiß Parteien, aber die einzelnen Parteien wissen nichts voneinander.

Datenbindung, Redux

In vielen "MVC-ähnlichen" Mustern macht das Observable eine Art "Benachrichtigung über geänderte Eigenschaften" verfügbar, die auch Informationen über die spezifische geänderte Eigenschaft enthält. Der Beobachter ist implizit, normalerweise vom Framework erstellt, und abonniert diese Benachrichtigungen über eine Bindungssyntax, um ein Objekt und eine Eigenschaft spezifisch zu identifizieren. Der "Ereignishandler" kopiert nur den neuen Wert und löst möglicherweise eine Aktualisierungs- oder Aktualisierungslogik aus.

Datenbindung zu Redux

Eine alternative Implementierung für die Datenbindung? Ok, hier ist eine dumme:

  • Es wird ein Hintergrundthread gestartet, der ständig die gebundene Eigenschaft eines Objekts überprüft.
  • Wenn dieser Thread feststellt, dass sich der Wert der Eigenschaft seit der letzten Überprüfung geändert hat, kopieren Sie den Wert in das gebundene Element.
JerKimball
quelle
Ich freue mich über Ihre Antwort und versuche, eine andere Datenbindungsidee umzusetzen.
Jess
@ Jessemon heh, kein Problem; Das Beobachtermuster ist definitiv der "abstrakt beste" Ansatz, den ich kenne, aber mein schreckliches kleines Beispiel würde auch "Datenbindung" durchführen, wenn auch auf chaotische und ineffiziente Weise.
JerKimball
7
Ehrlich gesagt, ich bin es leid, "Pub / Sub aka the Observer Pattern" zu hören, sie sind überhaupt nicht dasselbe. Pub / Sub ist ein Ereignissystem. Das Beobachtermuster verwendet ein Ereignissystem, um Ereignisse bei Änderung des Objekts AUTOMATISCH zu veröffentlichen. Wenn Sie Ereignisse manuell ausgeben, wenn Sie ein Objekt ändern, verwenden Sie das Beobachtermuster nicht.
BT
154

Es gibt zwei Hauptunterschiede zwischen Observer / Observable- und Publisher / Subscriber-Mustern:

  1. Das Observer / Observable- Muster wird meist synchron implementiert , dh das Observable ruft die entsprechende Methode aller seiner Beobachter auf, wenn ein Ereignis eintritt. Das Publisher / Subscriber- Muster wird meist asynchron implementiert (mithilfe der Nachrichtenwarteschlange).

  2. Im Observer / Observable- Muster sind sich die Beobachter des Observable bewusst . Während in Publisher / Subscriber Publisher und Subscriber sich nicht kennen müssen . Sie kommunizieren einfach mit Hilfe von Nachrichtenwarteschlangen.

Wie Sie richtig erwähnt haben, ist die Datenbindung ein Oberbegriff und kann entweder mit der Observer / Observable- oder der Publisher / Subscriber-Methode implementiert werden. Daten sind der Herausgeber / Abonnent.

Param
quelle
7
Ich habe JavaScript-Webanwendungen von O'Reilly gelesen ( shop.oreilly.com/product/0636920018421.do ). In Kapitel 2 implementiert Alex ein pub/subusing JS-Ereignis. Es handelt sich um eine Rückrufimplementierung, es handelt sich jedoch um ein synchrones Beispiel.
Jess
5
Ich habe das Buch nicht gelesen, aber wenn es mit JS "events" implementiert würde, wäre es asynchron, da Ereignisse per Definition asynchron sind.
Param
3
Hallo Jess, natürlich hast du recht. Es gibt keine Standarddefinition für diese Begriffe 😊
Param
14
Im Allgemeinen enthält ein Observable eine Liste von Beobachtern (diese Liste wird durchlaufen, um ein Ereignis an alle zu senden). Ein Herausgeber kennt im Allgemeinen nur eine Warteschlange, in der er seine Ereignisse / Nachrichten veröffentlicht. Es ist nicht bekannt, wie viele Verbraucher diese Warteschlange abonniert haben.
Param
7
Für mich ist dies der entscheidende Unterschied zwischen beiden: Auch im Beobachtermuster sind sich die Beobachter des Beobachtbaren bewusst. Während in Pub / Sub weder die Verlage noch die Verbraucher einander kennen müssen. Sie kommunizieren einfach mit Hilfe von Nachrichtenwarteschlangen. Gute Antwort!
Maryisdead
23

Ich bin ein bisschen amüsiert darüber, dass alle Antworten hier versucht haben, den subtilen Unterschied zwischen Observer- und Pub / Sub-Mustern zu erklären, ohne konkrete Beispiele zu nennen. Ich wette, die meisten Leser wissen immer noch nicht, wie sie jeden implementieren sollen, indem sie lesen, dass einer synchron und der andere asynchron ist.

Eine Sache zu beachten ist: Das Ziel dieser Muster ist es, Code zu entkoppeln

Der Beobachter ist ein Entwurfsmuster, bei dem ein Objekt (als Subjekt bezeichnet) eine Liste von Objekten in Abhängigkeit davon (Beobachter) verwaltet und diese automatisch über Statusänderungen informiert.

Beobachtermuster

Dies bedeutet, dass ein observable objecteine Liste hat, in der alle seine observers(normalerweise funktionalen) Funktionen gespeichert sind. und kann diese Liste durchlaufen und diese Funktionen aufrufen, wenn es sich gut anfühlt.

Einzelheiten finden Sie in diesem Beispiel für ein Beobachtermuster .

Dieses Muster eignet sich gut, wenn Sie auf Datenänderungen an einem Objekt warten und andere Benutzeroberflächenansichten entsprechend aktualisieren möchten.

Die Nachteile sind jedoch Observables, die nur ein Array zum Halten von Beobachtern verwalten (im Beispiel ist das Array observersList).

Es wird NICHT unterschieden, wie das Update ausgelöst wird, da es nur eine hat notify function, die alle in diesem Array gespeicherten Funktionen auslöst.

Wenn wir Beobachter-Handler basierend auf verschiedenen Ereignissen gruppieren möchten. Wir müssen das nur observersListauf ein Objectähnliches ändern

var events = {
    "event1": [handler1, handler2],
    "event2": [handler3]
}

Einzelheiten finden Sie in diesem Pubsub-Beispiel .

und die Leute nennen diese Variation als pub/sub. So können eventsSie je nach Veröffentlichung verschiedene Funktionen auslösen .

Qiang
quelle
Nun, das ist eine viel bessere, präzisere und klarere Antwort. :)
CoderX
Auf hohem Niveau habe ich immer gesagt, dass das Pub-Sub das Beobachtermuster ist, aber bei allem hat es unterschiedliche Geschmacksrichtungen.
Grimmiger
9

Ich stimme Ihrer Schlussfolgerung zu beiden Mustern zu. Für mich verwende ich jedoch Observable, wenn ich mich im selben Prozess befinde, und ich verwende Pub / Sub in prozessübergreifenden Szenarien, in denen alle Parteien nur den gemeinsamen Kanal kennen, nicht aber die Parteien .

Ich kenne keine anderen Muster, oder lassen Sie mich so sagen, ich habe nie ein anderes Muster für diese Aufgabe benötigt. Selbst die meisten MVC-Frameworks und Datenbindungsimplementierungen verwenden normalerweise intern das Beobachterkonzept.

Wenn Sie an prozessübergreifender Kommunikation interessiert sind, empfehle ich Ihnen:

"Enterprise Integration Patterns: Entwerfen, Erstellen und Bereitstellen von Messaging-Lösungen" - http://www.addison-wesley.de/9780321200686.html

Dieses Buch enthält viele Ideen zum Senden von Nachrichten zwischen Prozessen oder Klassen, die auch für prozessinterne Kommunikationsaufgaben verwendet werden können (es hat mir geholfen, lockerer zu programmieren).

Ich hoffe das hilft!

Rafa
quelle