190 likes | 354 Views
Agenda. O co w ogóle chodzi? Proste przykłady użycie zdarzeń Tworzymy swoje zdarzenie Jak to wszystko działa Pytania. O co w ogóle chodzi?. Problem komunikacji klas Możliwe (złe) rozwiązania: (Za) dużo metod i pól publicznych (Za) dużo metod i pól statycznych
E N D
Agenda • O co w ogóle chodzi? • Proste przykłady użycie zdarzeń • Tworzymy swoje zdarzenie • Jak to wszystko działa • Pytania
O co w ogóle chodzi? • Problem komunikacji klas • Możliwe (złe) rozwiązania: • (Za) dużo metod i pól publicznych • (Za) dużo metod i pól statycznych • Dużo przekazywania referencji – silne powiązania między klasami
Motywacja - przykład Aplikacja okienkowa z klasą formy i kilkoma klasami, które robią „coś” i stanowią jakiś wewnętrzny system. • Forma wyświetla informacje pochodzące z wnętrza systemu i przyjmuje żądania od użytkownika (czyli potrzebuje dostępu do systemu). • System korzysta z zasobów zewnętrznych i musi informować Formę o zmianach (czyli potrzebuje dostępu do formy). • Zarówno użytkownik, który widzi formę, jak i system i jego zewnętrzne zasoby (web serwisy, baza danych...) działają niezależnie, bez żadnej synchronizacji - wszystko dzieje się naraz. • System (jak i aplikacja w całości) jest wielowątkowy.
Zdarzenia - podstawy • Komunikacja przez metody. • Brak sztywnego wiązania klas ze sobą – pełna niezależność. • Możliwość dynamicznego (w czasie uruchomienia) łączenia i rozłączania klas w systemie.
Zdarzenia - przykład • Biblioteki Windows Forms i ASP.NET opierają się na zdarzeniach. • Korzystanie ze zdefiniowanych zdarzeń w tych bibliotekach odbywa się zupełnie bezmyślnie (co nie jest złe). • Obsługa zdarzenia sprowadza się do zaimplementowania (zazwyczaj prostej) metody.
Obsługiwanie zdarzeń • Tworzymy metodę (lub pozwalamy by Visual Studio zrobiło to za nas) obsługującą zdarzenie, o sygnaturze:public/private void metoda(object sender, EventArgs e); • Dodajemy metodę do listy metod obsługujących zdarzenie za pomocą operatora += (istnieje kilka innych możliwości):jakiśObiekt.Zdarzenie += metoda; • I to wszystko ;)
Tworzenie zdarzenia • (Opcjonalnie) Definiujemy klasę, która będzie nieść argumenty zdarzenia (klasa musi dziedziczyć z EventArgs). • Deklarujemy zdarzenie jako pole w klasie, za pomocą słowa kluczowego event:public event EventHandler<EArgs> Zdarzenie; • Zgłaszamy zdarzenie w wybranych miejscach klasy, za pomocą składni:Zdarzenie(this, args);
Kiedy stosować zdarzenia? • Do komunikacji w aplikacjach z GUI. • Do komunikacji między klasami lub (w niektórych przypadkach) wewnątrz jednej klasy. • W przypadku aplikacji wielowątkowych do komunikacji między wątkami. • Przy budowaniu bibliotek i kodu, który będzie używany przez inne osoby. • Do debugowania. • Do logowania (zapisujemy klasę logującą do wszystkich interesujących nas zdarzeń).
Kiedy nie stosować zdarzeń? • Gdy można rozwiązać komunikację prościej – np. wewnątrz jednej klasy – bez utraty niezależności i hermetyzacji poszczególnych fragmentów. • Zdarzenia nie służą do zgłaszania błędów (do tego służą wyjątki).
Jak działają zdarzenia? • Zdarzenia używają wewnętrznie delegatów do zapisu informacji o metodach i do wywoływania ich. • Delegaty można kojarzyć z wskaźnikami do funkcji w C. • Zdarzenia (słowo kluczowe event) jest tłumaczone przez kompilator (preprocesor?) na delegaty. • Delegaty są tłumaczone na specjalne obiekty, które przechowują listę adresów do obiektów i ich metod.
Jakie informacje przechowuje delegat • Adres obiektu i metody (wewnętrzne informacje – z reguły nie potrzebne programiście). • Listę argumentów i wartość zwracaną metody. • Wskaźniki do innych delegatów, które tworzą łańcuch wywołań.
Zastosowania delegatów • W wielu przypadkach delegaty można stosować zamiennie ze zdarzeniami. • Wywołanie wielu metod wewnątrz jednej lub wielu klas, przy czym lista metod może się zmieniać w czasie uruchomienia. • Przekazywanie „referencji” do metod a nie do całych obiektów. • Możliwość realizacji podejścia zbliżonego do programowania aspektowego (AOP).