Programowanie sterowane zdarzeniami

Z Wikipedii, wolnej encyklopedii
Skocz do: nawigacji, wyszukiwania

Definicja intuicyjna:

Programowanie sterowane zdarzeniami jest metodą tworzenia programów w środowiskach wieloprocesowych i pseudowieloprocesowych, które ma zapewnić możliwość jednoczesnej pracy wielu programów w jednej instancji systemu operacyjnego. Polega na przechodzeniu do wykonywania poszczególnych bloków asynchronicznie (niezależnie od czasu, jaki upłynął od zakończenia pracy poprzedniego modułu)

Programowanie sterowane zdarzeniami (Programowanie zdarzeniowe) – metodologia tworzenia programów komputerowych, która określa sposób ich pisania z punktu widzenia procesu przekazywania sterowania między poszczególnymi modułami tej samej aplikacji. Programowanie sterowane zdarzeniami jest mocno powiązane ze środowiskami wieloprocesowymi (nie mylić z komputerami wieloprocesorowymi), z graficznymi środowiskami systemów operacyjnych oraz z programowaniem obiektowym.

Jest to paradygmat programowania, według którego program jest cały czas bombardowany zdarzeniami (events), na które musi odpowiedzieć, i że przepływ sterowania w programie jest całkowicie niemożliwy do przewidzenia z góry.

Programowanie zdarzeniowe jest dominującym typem programowania GUI – zdarzenia to naciśnięcia myszy, klawiszy, żądania odświeżenia przez system okienkowy, różne zdarzenia sieciowe i inne.

Jest też używane przez wysoce wydajne serwery sieciowe – zdarzeniami są tu żądania połączenia, nadejście danych do odbioru, zwolnienie się miejsca w buforach wysyłania odbiorów, itd. W systemach uniksowych zwykle wszystkie połączenia (np. z plikami, sieciowe, z relacyjną bazą danych) mają charakter deskryptorów plików i na ich zbiorze jest wywoływana funkcja systemu operacyjnego select lub poll, która informuje na jakim deskryptorze wydarzyło się jakieś zdarzenie (zobacz artykuł: Wywołania systemowe Uniksa).

W programowaniu zdarzeniowym ważne jest żeby nie obsługiwać zbyt długo danego zdarzenia, bo blokuje się w ten sposób obsługę innych. W przypadku serwerów obniżyło by to znacznie wydajność, w przypadku GUI program zbyt wolno odpowiadałby na akcje użytkownika. Można to osiągnąć za pomocą asynchronicznego I/O, wielowątkowości, rozbijania zdarzenia na podzdarzenia i wielu innych mechanizmów.

Porównanie metod sterowania programem[edytuj | edytuj kod]

W starych systemach operacyjnych, takich jak na przykład DOS, w jednej chwili w komputerze mogła pracować tylko jedna aplikacja. Sterowanie jej działaniem odbywało się bądź poprzez jawne zadeklarowanie kolejności wykonania kodu (w programie jednoprzebiegowym), bądź poprzez pętlę obsługi wyboru opcji (w programie interaktywnym). Przykładowo fragment decyzyjny zapisany w pseudokodzie, który realizuje działanie interaktywne poprzez przemieszczanie się po prostym menu i wybór jego opcji z użyciem klawisza Enter, zaprezentowano poniżej:

PoczątekProgramu
WyświetlMenu(
  "1.Faktura",
  "2.Dodaj klienta",
  "3.Indeksacja bazy",
  "4.Koniec pracy")
AktywnaOpcja=1
PowtarzajPętlę:
  PodświetlMenu(AktywnaOpcja)
  PobierzDaneZKlawiatury(Znak)
  Jeżeli (Znak=Enter)
  wtedy WybierzAkcję(AktywnaOpcja):
    1: WystawFakturę
    2: DodajNowegoKlienta
    3: IndeksujBazęDanych
    4: PrzerwijPętlę
  KoniecWyboruAkcji
  Jeżeli (Znak=(Strzałka, Home, End, PgUp, PgDn))
  wtedy ZmieńAktywnąOpcję(AktywnaOpcja, Znak)
KoniecPętli
KoniecProgramu

Pętla z listingu była powtarzana tak długo, aż użytkownik wybrał opcję zakończenia programu. Wyjście z pętli było równoznaczne z końcem pracy.

W miarę rozwoju środowisk wieloprocesowych ten stary sposób obsługi interaktywności przestał się sprawdzać. W jednej chwili w systemie operacyjnym mogło pracować wiele różnych programów. Projektanci systemów nie mogli pozwolić poszczególnym programom na całkowite przejęcie kontroli nad systemem w taki sposób, by inne programy nic nie mogły robić. W związku z tym zaczęły pojawiać się pomysły na zdarzeniowe sterowanie programami. Idea tego rozwiązania była zupełnie inna od dotychczas stosowanej. Pętla odbierająca zdarzenia od urządzeń zewnętrznych, które pozwalały użytkownikowi komunikować się z programem, została utworzona tylko w jednym egzemplarzu dla całego systemu operacyjnego. Obsługą tej pętli (w tym przekazywaniem sterowania do poszczególnych programów) zajmował się sam system. Wszystkie procedury reakcji na zdarzenia nie są więc wywoływane jawnie w każdym programie. Zamiast tego we wszystkich programach tworzone są delegacje do obsługi odpowiednich zdarzeń. Dla przykładu starą wersję programu (z wcześniejszego listingu) można teraz zapisać w pseudokodzie w sposób pokazany poniżej:

PoczątekProgramu
ZaładujProceduryObsługiZdarzeńDoPamięci(
  WystawFakturę,
  DodajNowegoKlienta,
  IndeksujBazęDanych)
DodajDoSystemuMenu(
  "1.Faktura",
  "2.Dodaj klienta",
  "3.Indeksacja bazy",
  "4.Koniec pracy")
ZdefiniujPrzypisanieZdarzeńDoProcedur(
  NaZdarzenie WybranoOpcjęFaktura reaguj:
  WystawFakturę
  NaZdarzenie WybranoOpcjęDodajKlienta reaguj:
  DodajNowegoKlienta
  NaZdarzenie WybranoOpcjęReindeksacja reaguj:
  IndeksujBazęDanych
  NaZdarzenie WybranoOpcjęKoniecPracy reaguj:
  (UsuńZPamięciProceduryObsługiZdarzeń,
  UsuńDefinicjePrzypisaniaObsługiZdarzeńTegoProgramu,
  PrzekażSterowanieSystemowiOperacyjnemu)
)
PrzekażSterowanieSystemowiOperacyjnemu
KoniecProgramu

Analiza tego drugiego listingu ujawnia kilka znaczących różnic między „starą” pętlą obsługi zdarzeń a programowaniem sterowanym zdarzeniowo, oto one:

  • Nie występuje (w sposób jawny) pętla obsługi zdarzeń.
  • Rozdział zdarzeń scedowano na system operacyjny.
  • Konwersja zdarzeń z poziomu sprzętu (pochodzących od urządzeń zewnętrznych takich jak klawiatura, mysz czy ekran dotykowy) na zdarzenia typu znaczeniowego (na przykład „wybrano opcję menu”, „naciśnięto przycisk ekranowy” itd.).
  • Obsługa menu (zmiana wyglądu i przejście między jego opcjami) jest wykonywana przez system operacyjny (również niejawnie).

Związek programowania sterowanego zdarzeniami z programowaniem obiektowym[edytuj | edytuj kod]

Programowanie obiektowe zaczęło być popularne wraz z rozpowszechnieniem się środowisk graficznych, które miały charakter obiektowy, mimo iż często powstawały jeszcze w językach strukturalnych. Jednocześnie ze względu na swoje możliwości środowiska próbowały implementować wieloprocesowość. Nic więc dziwnego, że obie te metody tworzenia programów scaliły się ze sobą. Było to o tyle naturalne, że połączenie programowania obiektowego i sterowanego zdarzeniami znacznie podniosło walory obu tych technik. Zamiast uruchamiać jakieś procedury na podstawie zdarzenia, lepiej przesyłać go do konkretnego obiektu – niech on obsłuży je sobie we własnej piaskownicy. System zyskiwał na tym większą swobodę działania, nie musiał decydować o tym, jaką procedurę wykonać po naciśnięciu przycisku ekranowego 1, a jaką po 2. Odsyłał do obiektu-okna zdarzenie „naciśnięto przycisk ekranowy (numer przycisku)” i był wolny. Programowanie obiektowe zyskiwało hermetyzację i bezpieczeństwo. System nie wtrącał się do tego, co obiekt robi z tym zdarzeniem. Obecnie nikt już nie wyobraża sobie innego sposobu sterowania programem obiektowym niż za pomocą zdarzeń.

Przykłady[edytuj | edytuj kod]

Linki zewnętrzne[edytuj | edytuj kod]

Zobacz też[edytuj | edytuj kod]