We wzorze delegowanym tylko jeden obiekt może bezpośrednio nasłuchiwać zdarzeń innego obiektu. We wzorcu obserwatora dowolna liczba obiektów może nasłuchiwać zdarzenia określonego obiektu. Kiedy projektując klasę, która musi powiadamiać inne obiekty o zdarzeniach, dlaczego miałbyś kiedykolwiek używać wzorca delegowanego zamiast wzorca obserwatora? Widzę wzorzec obserwatora jako bardziej elastyczny. Możesz mieć tylko jednego obserwatora, ale przyszły projekt może wymagać wielu obserwatorów.
9
Odpowiedzi:
Sam w sobie nie ma wzorca delegowania. Zakładam, że masz na myśli wzór delegacji .
Jak rozumiem, są one kompletnie odwrotne i używane do różnych celów.
Zasadniczo we Wzorze obserwatora dowolna liczba obiektów obserwatora będzie nasłuchiwała zdarzenia na drugim obiekcie i działała na nim. Drugi obiekt nie ma wiedzy o swoich słuchaczach. Po prostu do nich wzywa.
Obiekt delegowany jest przekazywany do drugiego obiektu, który wywołuje metody bezpośrednio w delegacie. I na tym polega przewaga, której szukasz. Zamiast wysyłać jedną wiadomość do wielu słuchaczy, ma ona pełną kontrolę nad jednym obiektem (w danym momencie). Zobacz także Odwrócenie kontroli .
źródło
Patrzysz na rzeczy niepoprawnie. Obserwator widzi, że ma miejsce określone zdarzenie. Nie ma na to wpływu ani nie jest jego właścicielem. Delegat obsługuje określone zdarzenie i jest właścicielem procedury obsługi, nawet jeśli delegat jest właścicielem interfejsu do zdarzenia.
źródło
To kwestia kilku kompromisów.
Kompromisy:
Deleguj wzór:
Wzór obserwatora:
źródło
Wzorzec delegowania, jak rozumiem, jest znany jako mechanizm obsługi zdarzeń w innych językach, na przykład Delphi. Jako taka jest po prostu implementacją wzorca obserwatora z dużym ograniczeniem: tylko jeden słuchacz na raz.
Wada programów obsługi zdarzeń lub delegatów jest oczywista: tylko jeden obserwator.
Zaleta nie jest tak oczywista: wydajność. Za pomocą wzorca obserwatora możesz dodać wielu obserwatorów. Gdy wystąpi zdarzenie, o którym należy powiadomić obserwatora, należy wymienić go i wysłać do każdego z nich powiadomienie. Może to szybko zniszczyć każdą zaobserwowaną instancję, szczególnie gdy liczba zdarzeń wymagających powiadomienia jest również znacząca.
źródło
int (*my_int_f)(int)
w języku C). Zawsze myślałem, że ułatwią to zrozumienie, sprawiając, że będzie działać bardziej jak struct / enum. Wydarzenie to haczyk dla elastycznej tablicy słuchaczy, wykorzystującej pojedynczy podpis delegata. Mógłbyś to zrobić bez zdarzenia (dlatego zakładam, że OP oznaczało wzorzec delegacji, który jest bardzo inny), ale język ułatwia ci to.To jest stary post, ale i tak będę dzwonił, ponieważ inne odpowiedzi nie dotyczą tego, co dzieje się przy użyciu któregokolwiek z wzorów, wydaje się, że bardziej dotyczą teorii niż praktyki.
Jak działają delegacje i obserwatorzy
Dzięki Delegacji delegujący wybiera dokładnie, kto ma zareagować na dane zdarzenie w momencie utworzenia źródła potencjalnego zdarzenia. Możesz uważać tego słuchacza za jednego obserwatora . W przypadku wzorca Obserwator obserwator wybiera, kogo obserwuje, kiedy tylko ma na to ochotę; więc zależności są odwrócone, jeśli chodzi o obserwatora a delegację. Wzorem obserwatora myśl o gazecie i subskrybentach jak o obserwatorze. Obserwatorzy kontrolują, kiedy relacja zostanie utworzona. Z delegacją pomyśl o pracowniku i pracodawcy. Pracodawca kontroluje, kiedy tworzony jest związek i kto dokładnie odpowiada za określone wydarzenia. Pracownicy nie mogą wybrać zadań, nad którymi pracują ... ogólnie.
Niektórzy twierdzą, że delegacja może mieć jednego obserwatora, ale myślę, że prawdziwą różnicą między nimi jest sposób przypisywania obsługi zdarzeń. Nigdy nie zobaczysz delegata zarejestrowanego na wydarzenie. Nigdy się nie dowie, że nawet obsługuje zdarzenie, dopóki się ono nie wydarzy, a delegator wywoła publiczną metodę.
Przewaga delegacji
Ten wzór jest bardzo sztywny, a przy większości regresywnych projektów jest prostszy i ogólnie bardziej wytrzymały. Zmusza cię do zadeklarowania procedury obsługi zdarzeń z góry w momencie inicjowania źródła potencjalnego zdarzenia. Jeśli potrzebujesz kogoś do kierowania ruchem, przed otwarciem ulicy wyznaczysz dyrektora ruchu. W przypadku obserwatora pozwoliłbyś policjantowi ruchowemu wybrać, kiedy kierować ruchem w dowolnym momencie.
Wada delegacji
Wadą tego projektu jest to, że nie jest elastyczny. Jeśli wdrażasz jakiś kod do subskrybowania gazety, gazeta / delegator będzie musiał dokładnie określić, kto może czytać wiadomości w momencie ich tworzenia. Dzięki wzorowi obserwatorów można je później zarejestrować w dowolnym momencie, a gazeta będzie musiała jedynie wiedzieć, że zapisała się nowa osoba.
Kiedy wybrać delegację?
Jeśli na pewno potrzebujesz jednego konkretnego obserwatora (ów) i nie ma powodu, aby zmieniać osobę obserwującą, korzystny będzie sztywny wzór schematu przekazania uprawnień.
Na przykład potrzebujesz klasy / obiektu do obsługi tworzenia wyskakującego okienka dla określonego błędu. Nie ma wielu powodów, dla których w czasie wykonywania trzeba by było zmienić osobę zajmującą się konkretnym błędem, więc delegowanie błędu „Brak pamięci” do jednej jednostki byłoby sensowne. Utworzenie tablicy potencjalnych procedur obsługi, a następnie zarejestrowanie tych procedur pod kątem błędu „Brak pamięci” nie miałoby większego sensu; byłby to przykład użycia wzorca obserwatora w tej sytuacji. W czasie wykonywania możesz chcieć zmienić, które metody będą wywoływane lub jakie „delegowane” będą wywoływane dla zdarzeń zmiennych, ale zamiana programu obsługi zdarzeń dla określonego zdarzenia w czasie wykonywania nie jest normalna.
Nie jest niemożliwe zamiana delegatów, tak jak w przypadku obserwatora, jest to po prostu skomplikowane. W prawdziwym świecie być może chcesz zamienić policjantów z ruchu, aby nowy delegat obsługiwał ruch. Można argumentować, że lepszy projekt sprawiłby, że oryginalny delegat oddelegowałby komisariat policji, a nie jednego policjanta, ale dygresję ...
źródło