Jakie są „zapachy kodu”, które świadczą o tym, że wymagany jest model nasłuchiwania zdarzeń?

10

Jakie objawy w bazie kodu wskazują, że wymagane jest podejście do detektora zdarzeń?

Wydaje mi się, że gdy istnieją klasy, które muszą być wywoływane przez wiele, nieokreślone w zestawie innych klas w czasie projektowania, potrzebujesz jakiegoś szkieletu sygnalizacyjnego, ale chciałbym usłyszeć, jakie inne sytuacje mogłyby tam być ulepszone przez przejście na model oparty na zdarzeniach.

lurscher
źródło

Odpowiedzi:

8

Podejście Event / Listener stara się unikać ścisłego powiązania , więc wszystkie zapachy kodu, które to wskazują, wskazywałyby na podejście.

Na tej podstawie zasugerowałbym następujące objawy:

  • dużych konstruktorów , ponieważ każdy obiekt musi znać każdy inny obiekt i nie może bez niego działać. Być może w przebraniu tylu obj.set_dependecy(x)po wywołaniu konstruktora.

  • zależności dwukierunkowe , ponieważ bez zdarzeń, w imperatywnym języku, przepływ informacji jest w zasadzie „wypychany” (wywoływanie metody Someones)

  • „hierarchia wiedzy” jest trudna do ustalenia . Są to zależności dwukierunkowe , po prostu inny cel: jeśli istnieje A, który słucha B, A wie o B, ale B nie zna A, więc istnieje „hierachy”: niektóre obiekty nic nie wiedzą, inne znają inne itp. Na przykład podczas wdrażania MVC takiego: http://en.wikipedia.org/wiki/Model_View_Controller model zna tylko siebie, widok zna model, a kontroler zna widok i model.

keppla
źródło
1
Zależności dwukierunkowe są zdecydowanie najbardziej charakterystycznym znakiem, że należy przełączyć się na model sterowany zdarzeniami. Rozdęcie konstruktora może to znaczyć, ale częściej niż nie tylko oznacza, że ​​musisz zrobić więcej w zakresie agregacji, składu i / lub ogólnej abstrakcji (tj. Refaktoryzacji, a nie zmian projektowych).
Aaronaught
Masz rację. Próbowałem to uporządkować według łatwości wykrywania, a duże konstruktory są tak proste, że mogą zostać złapane przez wyrażenia regularne.
keppla,
6

Kiedy nie możesz lub nie powinieneś wiedzieć, co powinno reagować na zestaw komunikatów / sygnałów / zdarzeń.

Często dzieje się tak, gdy chcesz, aby „świat” wiedział o czymś, co dzieje się w module (klasie lub systemie klas), ale nie chcesz zawracać sobie głowy tym, co się nazywa.

Powiązany zapach kodu, by być konkretnym, występuje wtedy, gdy czujesz, że zaczynasz mieszać kod z niezależnych modułów, z których jeden robi coś, na co drugi powinien zareagować. Gdy zobaczysz, że musisz wywołać kod z modułu B w zależności od stanu / zdarzeń modułu A, potrzebujesz detektorów zdarzeń.

Klaim
źródło
3

Chciałbym zmienić twoje pytanie i powiedzieć: kiedy oparte na zdarzeniu nie jest właściwym rozwiązaniem dla aplikacji obiektowej? Myślę, że większość aplikacji OO może przynieść korzyści, jeśli są zaprojektowane jako producenci wydarzeń i konsumenci.

W końcu „wywołanie metody” jest w rzeczywistości wiadomością docierającą do obiektu, a obiekt jest odpowiedzialny za podjęcie decyzji, czy zrobi coś z komunikatem i wykonanie operacji. Nie jest to bardzo jasne w silnie typowanych językach, takich jak Java, ale staje się bardziej oczywiste w dynamicznych językach, takich jak Ruby.

Innym interesującym punktem projektowania aplikacji opartej na zdarzeniach jest to, że zwykle wewnętrzne komponenty muszą być odpowiednio izolowane i spójne, w przeciwnym razie kod bardzo szybko stanie się bałaganem. Jako przykład bardzo podoba mi się koncepcja architektury heksagonalnej zastosowana przez Alistaira Cockburna, ponieważ zwykle ten wzór tworzy lepszą enkapsulację i wymusza (moim zdaniem) bardziej spójne komponenty.

Myślę (ale prawdopodobnie się mylę), że jest to również związane z koncepcją Domain Driven Design zdarzeń domenowych , w której klasy domen emitują zdarzenia przechwytywane przez inne obiekty, a te obiekty emitują jeszcze inne zdarzenia (widać, gdzie to idzie: D). W tym wzorcu podoba mi się to, że interfejsy powinny modelować role, a nie implementacje.

Przepraszam, jeśli nie mam większego sensu, eksperymentowałem z tymi wzorcami w ciągu ostatnich kilku miesięcy z niesamowitymi wynikami, ale wciąż staram się zrozumieć pojęcia i ich zasięg.

Augusto
źródło
2

Zastanów się, co byś zrobił, gdyby nasłuchiwania zdarzeń (czyli wzorzec obserwatora) nie istniały.

Jeśli masz obiekt, który ma odniesienia do listy innych obiektów i wywołuje na nich metodę w danym momencie procesu, zdecydowanie powinieneś mieć tam zdarzenie.

Jeśli masz flagę na obiekcie, która mówi, że coś zostało zrobione i obserwujesz tę flagę z innych obiektów, zdecydowanie powinieneś był użyć modelu sterowanego zdarzeniami.

Nie należy jednak mylić tego z wywołaniem zwrotnym. Jeśli wywołasz metodę na innym obiekcie i przekażesz jej metodę na obiekcie źródłowym, do którego ma zostać odesłana w danym momencie, powinieneś zostawić to w ten sposób, zamiast używać detektora zdarzeń.

pdr
źródło