Czy tworzenie łańcuchów zdarzeń jest uważane za dobrą praktykę?

15

Od czasu do czasu napotykałem scenariusze, w których przed uruchomieniem zdarzenia należy spełnić kilka złożonych warunków. Co więcej, większość słuchaczy przeprowadza także dodatkowe kontrole, aby ustalić kierunek działania. To zmusiło mnie do zastanowienia się, czy lepszym rozwiązaniem byłoby myślenie w kategoriach mniejszych wydarzeń i pozwalanie im na wyzwalanie się w sobie.

Łączenie wydarzeń pozwoliłoby mi później wplatać się w dodatkowych słuchaczy przy dość niskim nakładzie pracy (możliwe naruszenie YAGNI?). Mój kod składałby się z prostych, łatwo zrozumiałych elementów, które nie powinny być trudne do zrozumienia dla innych.

Jednak możliwym minusem tego rozwiązania byłby fakt, że jeśli coś się nie powiedzie w łańcuchu (np. Wywołanie fałszywego zdarzenia z powodu błędu ludzkiego), bardzo trudno będzie złapać błąd.

Impreza jest dobrym pomysłem łączenia TM ? Jeśli nie, jakie są alternatywne metody utrzymywania porządku w kodzie związanym ze zdarzeniem?

gilden
źródło
1
W ciągu ostatnich kilku lat pracowałem nad biblioteką łańcuchów zdarzeń dla JavaScript. kayoub5.github.io/onQuery pozwala pisać złożone zdarzenia, takie jak <br> (A lub B), a następnie C, a następnie (D i E) jako {A + B} > C > {D & E}<br> Z pewnością pomaga pisać złożone rozwiązania w krótszym czasie, ale tyle razy wspomniano wcześniej, testowanie i debugowanie to wciąż problem.
Ayoub Kaanich

Odpowiedzi:

11

Czy tworzenie łańcuchów zdarzeń jest dobrym pomysłem?

To jedna z tych rzeczy, które wydają się być naprawdę dobrym pomysłem, dopóki ich nie użyjesz.

Bardzo trudno jest skonfigurować zdarzenia kaskadowe bez jakiejś domyślnej zależności od porządku. Trudno je skonfigurować bez powodowania problemów z powodu nieskończonych pętli i sporadycznych wycieków pamięci. Utrudniają projektowanie klas ze względu na sprzężenie spowodowane zdarzeniami, które muszą wiedzieć, gdzie dołączyć, i gdzie należy kaskadowo.

I są bardzo trudne do debugowania i wnioskowania o kodzie.

Teraz czasem można ich używać w stosunkowo ograniczonych scenariuszach, w których struktura kodu ogranicza niektóre z tych problemów. W interfejsach użytkownika zdarzenia kaskadowe można wykorzystać do wyzwolenia hierarchii, ponieważ ta struktura hierarchii pomaga ograniczyć problemy z własnością i pętlami.

Mimo to obecnie znacznie częściej stwierdzam, że akceptuję delegata w konstruktorze dla tego rodzaju rozszerzalnego zachowania, niż pozwalam, aby arbitralne zachowanie zapadło w czasie działania.

Telastyn
źródło
Kilka świetnych punktów, szczególnie ten dotyczący hierarchii interfejsu użytkownika.
vaughandroid
2

Łączenie zdarzeń jest dobrym pomysłem, jeśli

  • Jest to ogólnie odpowiednie dla twojego scenariusza. Prostym przykładem jest działanie interfejsu użytkownika uruchamiające inne zdarzenia wizualne.
  • Każde wydarzenie jest niezależne i możliwe do zarządzania. Nie chcesz, aby rozwiązanie stało się zbyt kłopotliwe.
  • Przepływ kontroli jest łatwy do naśladowania. Musi być zaimplementowany na platformie w języku łatwym dla programisty. Jeśli chcesz wyśledzić „magiczne” metody śledzenia tego, co się dzieje, idziesz niewłaściwą ścieżką.

Bardzo ważne jest przemyślenie rozwiązania i uogólnienie niektórych rzeczy przed rozpoczęciem budowy systemu. Na przykład w języku OO powinieneś mieć podstawowy interfejs lub klasę abstrakcyjną jako podstawę wszystkich zdarzeń. Ta klasa powinna zawierać takie rzeczy jak rejestrowanie / debugowanie. Możesz także chcieć mieć uogólnioną klasę zarządzania zdarzeniami do płynnego zarządzania awariami.

Matt S.
źródło
2

Mówiąc z punktu widzenia kogoś, kto kiedyś spędził kilka dni na wyszukiwaniu błędu związanego z łańcuchem zdarzeń, jest to bardzo zły pomysł (sm). Ukrywasz przepływ kontroli, który (jak zauważyłeś) może sprawić, że debugowanie stanie się koszmarem. Sytuacja, w której byłem, powstała, gdy ktoś dodał kod obsługi błędów, który resetuje kontrolkę. Doprowadziło to do łańcucha programów onPropertyChangeobsługi, które zakończyły odświeżanie kontrolki, która miała moduł obsługi błędów, co doprowadziło do ponownego zresetowania drugiej kontroli i tak dalej. Zasadniczo interfejs użytkownika po prostu blokuje się, gdy procesor jest ustawiony na 100%.

Jeśli masz jakiś sposób, aby zapobiec wyzwalaniu procedur obsługi zdarzeń więcej niż jeden raz dla tego samego zdarzenia głównego, możesz tego uniknąć, ale mogę sobie wyobrazić sytuacje, w których możesz chcieć wywoływania wielu procedur obsługi zdarzeń.

TMN
źródło
1
Brzmi to jak problem z konkretną implementacją, a nie z ogólną koncepcją.
Matt S
Myślę, że problem z niedeterministycznym przepływem sterowania jest nieodłączny od projektu. Chyba że kodujesz bardzo specyficzne przepływy i nie używasz ogólnego mechanizmu pub / podtyp.
TMN
2

Prawidłowe wdrożenie łączenia zdarzeń jest trudne z wszystkich powodów wymienionych przez innych.

Jest to jednak podstawowa przesłanka większości silników reguł. JBoss Drools, IBM jRules, PegaSystems, Corticon i FICO Blaze Advisor są głównymi systemami zarządzania regułami biznesowymi (BRMS), które pozwalają użytkownikom deklarować reguły uruchamiane na podstawie zdarzeń występujących w systemach. Zarówno łańcuchy do przodu, jak i do tyłu są możliwe i wykonalne.

Język Prolog i jego pochodne opierają się na tym samym pojęciu.

Algorytmy, o których mowa, nie są proste, debugowanie MOŻE być uciążliwe, ale w modelu można znaleźć wiele wartości.

Matthew Flynn
źródło
1

Jedną z potencjalnych wad jest to, że dość łatwo przypadkowo skończyć z zapętlonymi aktualizacjami. np. A -> B -> C -> A -> B ...

Innym podejściem jest tworzenie złożonych zdarzeń odpowiedzialnych za odpalenie sekwencji zdarzeń. Oznacza to, że nie powinieneś utknąć w pętli i daje ci jedno miejsce do łapania błędów / etc. Odniosłem z tym pewien sukces, choć wprawdzie nie wykorzystałem go do niczego szczególnie skomplikowanego (jeszcze!).

Vaughandroid
źródło