Czytałem Gang Of Four , aby rozwiązać niektóre z moich problemów i natrafiłem na wzorzec Mediatora .
Wcześniej korzystałem z Observera w moich projektach do tworzenia aplikacji GUI. Jestem trochę zdezorientowany, ponieważ nie widzę między nimi dużej różnicy. Przeglądałem, aby znaleźć różnicę, ale nie mogłem znaleźć trafnej odpowiedzi na moje zapytanie.
Czy ktoś mógłby mi pomóc w rozróżnieniu między nimi za pomocą jakiegoś dobrego przykładu, który wyraźnie je rozgranicza?
Programmers.StackExchange
została odrzucona, ale zamieściłem tam podobny post , ponieważ byłem zainteresowany odpowiedzią. Niektóre odpowiedzi mogą być interesujące. :)ChangeManager
dlaObserver
wzorca, który używaMediator
. widzieć; paginas.fe.up.pt/~aaguiar/as/gof/hires/pat5g.htm#samplecodeOdpowiedzi:
Wzorzec obserwatora: definiuje zależność jeden-do-wielu między obiektami, dzięki czemu gdy jeden obiekt zmieni stan, wszystkie jego elementy zależne są powiadamiane i aktualizowane automatycznie.
Wzorzec Mediator: Zdefiniuj obiekt, który zawiera sposób interakcji zestawu obiektów. Mediator promuje luźne powiązania, uniemożliwiając obiektom bezpośrednie odwoływanie się do siebie, i pozwala niezależnie zmieniać ich interakcje.
Źródło: dofactory
Przykład:
Wzorzec obserwatora: Klasa A, może mieć zarejestrowanych zero lub więcej obserwatorów typu O. Kiedy coś w A zostanie zmienione, powiadamia to wszystkich obserwatorów.
Wzorzec mediatora: masz pewną liczbę wystąpień klasy X (lub może nawet kilka różnych typów: X, Y i Z) i oni chcą się ze sobą komunikować (ale nie chcesz, aby każda z nich miała wyraźne odniesienia do każdego z nich other), więc tworzysz klasę mediatora M. Każda instancja X ma odniesienie do współdzielonej instancji M, za pośrednictwem której może komunikować się z innymi instancjami X (lub X, Y i Z).
źródło
W oryginalnej książce, która ukuła terminy Obserwator i Mediator, Wzorce projektowe, Elementy oprogramowania obiektowego wielokrotnego użytku , mówi, że wzorzec Mediatora można zaimplementować za pomocą wzorca obserwatora. Jednak można to również zaimplementować, mając Koledzy (którzy są z grubsza równoważne z Podmiotami wzorca Obserwatora), mając odniesienie do klasy Mediator lub interfejsu Mediator.
Jest wiele przypadków, w których chciałbyś użyć wzorca obserwatora, kluczem jest to, że obiekt nie powinien wiedzieć, jakie inne obiekty obserwują jego stan.
Mediator jest nieco bardziej szczegółowy, unika sytuacji, w której klasy komunikują się bezpośrednio, ale zamiast tego za pośrednictwem mediatora. Pomaga to zasadzie pojedynczej odpowiedzialności, umożliwiając przekazanie komunikacji do klasy, która po prostu zajmuje się komunikacją.
Klasyczny przykład Mediatora jest w GUI, gdzie naiwne podejście może prowadzić do kodu po kliknięciu przycisku mówiącego „jeśli panel Foo jest wyłączony, a panel Bar ma etykietę z napisem„ Proszę wprowadzić datę ”, to nie dzwoń do serwera, inaczej idź dalej ”, gdzie w przypadku wzorca Mediator mógłby powiedzieć„ Jestem tylko przyciskiem i nie mam nic ziemskiego, wiedząc o panelu Foo i etykiecie na panelu Bar, więc po prostu zapytam mojego mediatora, czy dzwonię do serwera jest teraz w porządku ”.
Lub, jeśli Mediator jest zaimplementowany przy użyciu wzorca Observer, przycisk będzie mówił „Hej, obserwatorzy (w tym mediator), mój stan się zmienił (ktoś mnie kliknął). Zrób coś z tym, jeśli ci zależy”. W moim przykładzie to prawdopodobnie ma mniej sensu niż bezpośrednie odwoływanie się do mediatora, ale w wielu przypadkach użycie wzorca Observer do implementacji Mediatora miałoby sens, a różnica między Observer i Mediator byłaby bardziej intencjonalna niż różnica w samym kodzie.
źródło
Obserwator
1. Bez
Klient1 : Hej Temat , kiedy się zmieniasz?
Klient2 : Kiedy zmieniłeś Temat ? Nie zauważyłem!
Klient3 : Wiem, że Temat się zmienił.
2. Z
Mediator
1. Bez
2. Z
źródło
Te wzorce są używane w różnych sytuacjach:
Wzorzec mediatora jest używany, gdy masz dwa podsystemy z pewnymi zależnościami, a jeden z nich wymaga zmiany, a ponieważ możesz nie chcieć zmieniać systemu zależnego od drugiego, możesz chcieć wprowadzić mediatora, który rozdzielić zależności między nimi. W ten sposób, gdy jeden z podsystemów ulegnie zmianie, wszystko, co musisz zrobić, to zaktualizować mediatora.
Wzorzec obserwatora jest używany, gdy klasa chce zezwolić innym klasom na rejestrację i otrzymywanie powiadomień o zdarzeniach, np. ButtonListener itp.
Oba te wzorce pozwalają na mniejsze sprzężenie, ale są zupełnie inne.
źródło
Weźmy przykład: rozważmy, że chcesz zbudować dwie aplikacje:
mediator
Budując aplikację do czatu, wybierzesz
mediator
wzorzec projektowy.Dlaczego wolimy
mediator
? wystarczy spojrzeć na jego definicję:Jak działa magia? Najpierw stworzymy mediatora czatu i sprawimy, że obiekty osób będą się do niego rejestrować, aby miał dwukierunkowe połączenie z każdą osobą (osoba może wysłać wiadomość za pomocą mediatora czatu, ponieważ ma do niej dostęp, a mediator czatu będzie miał do niej dostęp otrzymana metoda przedmiotu osoby, ponieważ on również ma do niej dostęp)
obserwator
Budując aplikację wzywania 911, będziesz wybierać
observer
wzorzec projektowy.observer
obiekt karetki chce być informowany o sytuacji awaryjnej, aby mógł podjechać pod adres i udzielić pomocy.observable
utrzymuje łączność z każdym w karetceobservers
i powiadamia ich, gdy potrzebna jest pomoc (lub zdarzenie generujące).Dlaczego wolimy
observer
? wystarczy spojrzeć na jego definicję:Różnice:
mediator
ma dwukierunkową komunikację między obiektami osób (wysyłanie i odbieranie), podczas gdy operatorobservable
ma tylko jednokierunkową komunikację (nakazuje karetceobserver
jechać i kończyć).mediator
może sprawić, że obiekty osób wchodzą w interakcję (nawet jeśli nie jest to komunikacja bezpośrednia), karetkiobservers
rejestrują tylkoobservable
zdarzenia operatora .mediator
, a także czatmediator
zachowuje odniesienie do każdej z osób. Gdzie karetkaobserver
nie ma odniesienia do operatoraobservable
, tylko operatorobservable
ma odniesienie do każdej karetkiobserver
.źródło
Chociaż oba są używane do zorganizowanego sposobu informowania o zmianach stanu, różnią się nieco strukturalnie i semantycznie IMO.
Observer jest używany do rozgłaszania zmiany stanu określonego obiektu z samego obiektu. Zatem zmiana zachodzi w centralnym obiekcie, który jest również odpowiedzialny za jej sygnalizację. Jednak w Mediatorze zmiana stanu może nastąpić w dowolnym obiekcie, ale jest transmitowana przez mediatora. Więc jest różnica w przepływie. Ale nie sądzę, że ma to wpływ na zachowanie naszego kodu. Możemy użyć jednego lub drugiego, aby osiągnąć to samo zachowanie. Z drugiej strony ta różnica może mieć pewien wpływ na koncepcyjne rozumienie kodu.
Widzisz, głównym celem używania wzorców jest raczej stworzenie wspólnego języka między programistami. Tak więc, kiedy widzę mediatora, osobiście rozumiem wiele elementów próbujących komunikować się za pośrednictwem jednego brokera / koncentratora, aby zmniejszyć szum komunikacji (lub promować SRP), a każdy obiekt jest równie ważny pod względem zdolności sygnalizowania zmiany stanu. Na przykład pomyśl o wielu samolotach zbliżających się do lotniska. Każdy powinien komunikować się przez pylon (mediatora), zamiast komunikować się ze sobą. (Pomyśl o 1000 samolotach komunikujących się ze sobą podczas lądowania - to byłby bałagan)
Jednak kiedy widzę obserwatora, oznacza to, że są pewne zmiany stanu, które mogą mnie interesować i powinienem zarejestrować / zasubskrybować, aby słuchać poszczególnych zmian stanu. Istnieje centralny obiekt odpowiedzialny za sygnalizację zmian stanu. Na przykład, jeśli zależy mi na konkretnym lotnisku w drodze z punktu A do B, mogę zarejestrować się na to lotnisko, aby obejrzeć transmitowane wydarzenia, na przykład pusty pas startowy lub coś w tym rodzaju.
Mam nadzieję, że to jasne.
źródło
@cdc doskonale wyjaśnił różnicę w zamiarze.
Dodam więcej informacji na górze.
Obserwator : umożliwia powiadomienie o zdarzeniu w jednym obiekcie do innego zestawu obiektów (instancje różnych klas)
Mediator : scentralizuj komunikację między zbiorem obiektów utworzonych z określonej klasy.
Struktura wzorca Mediator z dofactory :
Mediator : definiuje interfejs do komunikacji między współpracownikami.
Kolega : to klasa abstrakcyjna, która definiuje wydarzenia, które mają być przekazywane między kolegami
ConcreteMediator : wdraża zachowanie kooperacyjne poprzez koordynację obiektów Colleague i opiekę nad współpracownikami
ConcreteColleague : implementuje operacje zawiadomieniem otrzymanym przez Pośrednika , który został wygenerowany przez innego współpracownika
Jeden przykład z prawdziwego świata:
Utrzymujesz sieć komputerów w topologii Mesh . Jeśli zostanie dodany nowy komputer lub istniejący komputer zostanie usunięty, wszystkie inne komputery w tej sieci powinny wiedzieć o tych dwóch zdarzeniach.
Zobaczmy, jak pasuje do niego wzorzec Mediatora.
Fragment kodu:
wynik:
Wyjaśnienie:
źródło
Jak O tym wyjaśnieniu Technicznie zarówno Observer, jak i Mediator są takie same i służą do zapewnienia oddzielonego sposobu komunikacji komponentów, ale użycie jest inne.
Podczas
obeserver
powiadamiania subskrybowanych komponentów o zmianach stanu (na przykład utworzenie nowego rekordu bazy danych),mediator
komendy zarejestrowały komponenty w celu zrobienia czegoś związanego z przepływem logiki biznesowej (wysłanie wiadomości e-mail do użytkownika w celu zresetowania hasła).Obserwator
Mediator
źródło