Różnica między Observer, Pub / Sub i Data Binding


163

Jaka jest różnica między wzorcem obserwatora , publikowaniem / subskrypcją i wiązaniem danych ?

Szukałem trochę na Stack Overflow i nie znalazłem żadnych dobrych odpowiedzi.

Doszedłem do wniosku, że powiązanie danych jest terminem ogólnym i istnieją różne sposoby jego implementacji, takie jak wzorzec obserwatora lub wzorzec Pub / Sub. Ze wzorcem Observer, Observable aktualizuje swoje Observers. Dzięki Pub / Sub 0-wielu wydawców może publikować wiadomości określonych klas, a 0-wielu subskrybentów może subskrybować wiadomości określonych klas.

Czy istnieją inne wzorce implementacji „wiązania danych”?


Znalazłem inny: brudne sprawdzanie, co robi Angular.js. Więcej informacji tutaj: stackoverflow.com/questions/9682092/databinding-in-angularjs
Jess

Odpowiedzi:


143

Oto moje podejście do trzech:

Wiązanie danych

Zasadniczo oznacza to po prostu, że „wartość właściwości X na obiekcie Y jest semantycznie związana z wartością właściwości A w obiekcie B. Nie są poczynione żadne założenia co do tego, w jaki sposób Y zna lub otrzymuje zmiany w obiekcie B.

Observer lub Observable / Observer

Wzorzec projektowy, za pomocą którego obiekt jest nasycony możliwością powiadamiania innych o określonych zdarzeniach - zwykle wykonywanych przy użyciu rzeczywistych zdarzeń, które są czymś w rodzaju szczelin w obiekcie o kształcie określonej funkcji / metody. Obserwowalny to ten, który dostarcza powiadomienia, a obserwator otrzymuje te powiadomienia. W .net, obserwowalne może ujawnić zdarzenie, a obserwator subskrybuje to zdarzenie za pomocą haka w kształcie „obsługi zdarzenia”. Nie poczyniono żadnych założeń co do konkretnego mechanizmu, w którym pojawiają się powiadomienia, ani co do liczby obserwatorów, których jeden obserwowalny może zgłosić.

Pub / Sub

Inna nazwa (być może z większą semantyką „rozgłoszeniową”) wzorca Observable / Observer, która zwykle sugeruje bardziej „dynamiczny” smak - obserwatorzy mogą subskrybować lub anulować subskrypcję powiadomień, a jeden obserwowalny może „krzyczeć” do wielu obserwatorów. W .NET można użyć do tego standardowych zdarzeń, ponieważ zdarzenia są formą MulticastDelegate, a więc mogą obsługiwać dostarczanie zdarzeń do wielu subskrybentów, a także obsługiwać anulowanie subskrypcji. Pub / Sub ma nieco inne znaczenie w pewnych kontekstach, zwykle wiąże się z większą „anonimowością” między zdarzeniem a zdarzeniem, co może być ułatwione przez dowolną liczbę abstrakcji, zwykle z udziałem jakiegoś „pośrednika” (takiego jak kolejka wiadomości), który wie wszystko imprezy, ale poszczególne strony nie wiedzą o sobie.

Wiązanie danych, redux

W wielu wzorcach „podobnych do MVC”, obserwowalne ujawniają pewien rodzaj „powiadomienia o zmianie właściwości”, które zawiera również informacje o zmianie określonej właściwości. Obserwator jest niejawny, zwykle tworzony przez strukturę i subskrybuje te powiadomienia za pomocą jakiejś składni powiązania, aby konkretnie zidentyfikować obiekt i właściwość, a „program obsługi zdarzeń” po prostu kopiuje nową wartość, potencjalnie wyzwalając jakąkolwiek aktualizację lub logikę odświeżania.

Wiązanie danych ponownie Redux

Alternatywna implementacja wiązania danych? Ok, oto głupi:

  • uruchamiany jest wątek w tle, który stale sprawdza powiązaną właściwość obiektu.
  • jeśli ten wątek wykryje, że wartość właściwości zmieniła się od czasu ostatniego sprawdzenia, skopiuj wartość do powiązanego elementu.

Doceniam twoją odpowiedź i próbuję wdrożyć inny pomysł na wiązanie danych.
Jess,

@jessemon heh, nie ma problemu; wzorzec obserwatora jest zdecydowanie „abstrakcyjnie najlepszym” podejściem, z którego jestem świadomy, ale mój okropny mały przykład również „wiązałby dane”, aczkolwiek w sposób chaotyczny i nieefektywny.
JerKimball

7
Szczerze mówiąc, mam dość słuchania „pub / sub aka wzorzec obserwatora”, wcale nie są tym samym. Pub / sub to system zdarzeń, wzorzec obserwatora używa systemu zdarzeń do AUTOMATYCZNEGO publikowania zdarzeń przy zmianie obiektu. Jeśli ręcznie emitujesz zdarzenia za każdym razem, gdy zmieniasz obiekt, nie używasz wzorca obserwatora.
BT

154

Istnieją dwie główne różnice między wzorcami obserwatorów / obserwowalnych i wydawców / subskrybentów:

  1. Wzorzec Observer / Observable jest przeważnie implementowany w sposób synchroniczny , tj. Obserowalny wywołuje odpowiednią metodę wszystkich swoich obserwatorów, gdy wystąpi jakieś zdarzenie. Wydawca / Abonent wzór jest głównie prowadzona w asynchronicznym sposób (przy użyciu kolejki wiadomości).

  2. We wzorcu obserwator / obserwowalny , obserwatorzy są świadomi tego, co można zaobserwować . Natomiast w przypadku wydawcy / subskrybenta wydawcy i subskrybenci nie muszą się znać . Po prostu komunikują się za pomocą kolejek wiadomości.

Jak słusznie wspomniałeś, powiązanie danych jest terminem ogólnym i można je zaimplementować za pomocą metody Obserwator / Obserwowalny lub Wydawca / Subskrybent. Dane są wydawcą / subskrybentem.


7
Czytałem aplikacje internetowe JavaScript autorstwa O'Reilly ( shop.oreilly.com/product/0636920018421.do ). W rozdziale 2 Alex implementuje pub/subzdarzenia using JS. Jest to implementacja typu callback, ale jest to przykład synchroniczny .
Jess

5
Nie czytałem tej książki, ale gdyby została zaimplementowana przy użyciu „zdarzeń” JS, byłaby asynchroniczna, ponieważ zdarzenia są asynchroniczne z definicji.
Param

3
Cześć Jess, oczywiście, że masz rację. Nie ma standardowej definicji tych terminów 😊
Param,

14
Ogólnie rzecz biorąc, obserwowalny ma listę obserwatorów z sobą (iteruje tę listę, aby wysłać zdarzenie do wszystkich). Wydawca jest na ogół świadomy istnienia tylko kolejki, w której publikuje swoje zdarzenia / komunikaty. Nie wie, ilu konsumentów zapisało się do tej kolejki.
Param

7
Dla mnie jest to zasadnicza różnica między nimi dwoma: także we wzorze obserwatora obserwatorzy są świadomi tego, co można zaobserwować. Natomiast w Pub / Sub ani wydawcy, ani konsumenci nie muszą się znać. Po prostu komunikują się za pomocą kolejek wiadomości. Świetna odpowiedź!
maryisdead

23

Jestem trochę rozbawiony, że wszystkie odpowiedzi tutaj próbowały wyjaśnić subtelną różnicę między wzorcami Observer i Pub / Sub bez podawania konkretnych przykładów. Założę się, że większość czytelników nadal nie wie, jak zaimplementować każdy z nich, czytając jeden jest synchroniczny, a drugi asynchroniczny.

Należy zwrócić uwagę: celem tych wzorców jest próba oddzielenia kodu

Obserwator to wzorzec projektowy, w którym obiekt (znany jako podmiot) utrzymuje listę zależnych od niego obiektów (obserwatorów), automatycznie powiadamiając ich o wszelkich zmianach stanu.

Wzorzec obserwatora

Oznacza to, że observable objectma listę, na której przechowuje wszystkie swoje observers(zwykle są to funkcje). i może przeglądać tę listę i wywoływać te funkcje, gdy czuje się dobrze.

zobacz ten przykład wzorca obserwatora, aby uzyskać szczegółowe informacje.

Ten wzorzec jest dobry, gdy chcesz nasłuchiwać zmian danych w obiekcie i odpowiednio aktualizować inne widoki interfejsu użytkownika.

Ale Wady są Observables, utrzymują tylko jedną tablicę do przechowywania obserwatorów (w przykładzie tablica jest observersList).

NIE rozróżnia sposobu wyzwalania aktualizacji, ponieważ ma tylko jedną notify function , która uruchamia wszystkie funkcje przechowywane w tej tablicy.

Jeśli chcemy pogrupować obsługę obserwatorów na podstawie różnych zdarzeń. Musimy tylko zmienić to observersListna coś Objectpodobnego

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

zobacz ten przykład pubsub po szczegóły.

a ludzie nazywają tę zmianę jako pub/sub. Możesz więc wyzwalać różne funkcje w oparciu o eventsopublikowane.


To znacznie lepsza, zwięzła i jasna odpowiedź. :)
CoderX

Na wysokim poziomie zawsze mówiłem, że pub jest wzorem obserwatora, ale ze wszystkim ma różne smaki.
Ponury

9

Zgadzam się z twoim wnioskiem dotyczącym obu wzorców, niemniej jednak używam Observable, gdy jestem w tym samym procesie i używam Pub / Sub w scenariuszach międzyprocesowych, w których wszystkie strony znają tylko wspólny kanał, ale nie strony .

Nie znam innych wzorców, albo powiem w ten sposób, nigdy nie potrzebowałem innych wzorców do tego zadania. Nawet większość frameworków MVC i implementacji powiązań danych zwykle używa wewnętrznie koncepcji obserwatora.

Jeśli interesuje Cię komunikacja międzyprocesowa, polecam:

„Wzorce integracji przedsiębiorstwa: projektowanie, tworzenie i wdrażanie rozwiązań do obsługi wiadomości” - http://www.addison-wesley.de/9780321200686.html

Ta książka zawiera wiele pomysłów na to, jak przesyłać komunikaty między procesami lub klasami, które można wykorzystać nawet w zadaniach komunikacji wewnątrzprocesowej (pomogło mi to programować w bardziej luźny sposób).

Mam nadzieję, że to pomoże!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.