Observer Struktura -každodenní použití -základní struktura -vlastnosti -implementace -možnosti v C#/WPF 1 1
Observer – idea Follow(sledování) na Twitteru Pokud někoho sleduji, dostanu upozornění vždy, když přidá příspěvek Můžu sledovat více lidí Můžu mít více odběratelů Sledování můžu kdykoliv zrušit a později obnovit Observer funguje úplně stejně
Observer – idea Sledování na Twitteru Upozornění = Update() Follow = Attach() Unfollow = Detach() subject Observer je o propojení dvou druhů objektů – subject a observer observer
Každodenní použití v C#/WPF Subject push - potencialne neefektivni, obzvlast pri slozitejsich datech Attach Detach 4 4
Observer – struktura Subject (Publisher) ConcreteSubject Seznam observerů Rozhraní pro přidání/odebrání ConcreteSubject Uchovává a mění stav Notifikuje své observery Observer (Subscriber) Rozhraní pro aktualizace stavu ConcreteObserver Reference na ConcreteSubject Uchovává potřebný stav Implementuje update Interface Interface Jedno z možných variant, další možnosti na následujících slajdech 5 5
Vzájemná spolupráce – zajímavější Observer vyvolá změnu Sám se zatím nemění ! Změna stavu až po notifikaci Oberver vyvolal zmenu v subjektu – vi, jakou zmenu vyvolal, takze neni potreba aby byl notifikovanej. Ale nebudeme zeslozitovat fungovani – a proto musi pockat az ho subjekt notifikuje o zmene kterou on sam vyvolal. Stejně pro ostatní observery 6 6
Observer – vlastnosti Návrhový vzor Observer – jak funguje Závislost 1:n Notifikace o změnách stavu Subjektu Observeři reagují Důsledek = rozdělení zodpovědnosti, odlehčení funkcionality Decoupling/loose coupling Menší, znovu použitelné objekty Redukuje závislosti Netřeba modifikovat subjekt pro přidáváni observerů Observery lze přidávat/odebírat za běhu Vztah mezi subjektem a observery je jasně pochopitelný Lepší čitelnost kódu/návrhu Sledování změn objektu Objekt změní stav ostatní objekty zareagují Bez přímé vazby mezi objekty Subjekt neví o observerech Nezajímá nás počet reagujících objektů 7 7
Observer – detaily implementace Posílání informace o změně Push model Subject v Updatu posílá data, která se změnila Ušetří tím práci Observerům Pull model Subject v Updatu neposílá nic observer si sám vyžádá potřebná data od subjektu Možnosti jak předat informaci o změně Observerům push - potencialne neefektivni, obzvlast pri slozitejsich datech 8 8
Observer – detaily implementace Více sledovaných subjektů Už nestačí metoda Update() Observer totiž neví, který subjekt update vyvolal Vyřeší se předáním subjektu jako argument Řešení notifikace Ve všech funkcích měnících stav (klasika) atomické, může být ale neefektivní Na vhodném místě (až po sekvenci změn) Chtěli bychom aby tato sekvence byla atomická Je potřeba zařídit něco jako transakce Větší náchylnost k chybám 9 9
Kliknuti = Co me zajima (aspekt) Observer – detaily implementace Sledování pouze specifických změn Observer specifikuje, jaký druh změn jej zajímá document.getElementById("myBtn").addEventListener("click", function(){ document.getElementById("demo").innerHTML = "Hello World"; }); Přidání informace o druhu změny do metody update NotifyCollectionChangedAction – Add, Remove, Replace, Move, Reset Různé metody update pro různé změny WPF Button – Click, MouseEnter, MouseLeave, … Button = subject Kliknuti = Co me zajima (aspekt) Funkce = observer push - potencialne neefektivni, obzvlast pri slozitejsich datech 10 10
Observer – problémy Pozor na rušení objektů Můžou vznikat neplatné reference Může docházet k Memory leaku delegate v C# drží referenci na příslušný objektu Neznámá cena změny subjektu I malá změna Subjectu může stát hodně času Problém například v GUI – okno zamrzne 11 11
Observer – proč se hodí v následujících případech Twitter / Facebook funkcionalita sledování/followers Jiným způsobem ani udělat nejde GUI framework Šlo by přece udělat přes dědičnost ... Takze jaka je situace, kdyz programuju to tlacitko. 12 12
Button - situace Button Programuji GUI framework a chci mít hotové tlačítko Funkční, otestované Dopředu vím, že při kliknutí bude programátor chtít, aby se něco dělo Nějaké objekty budou nějak reagovat Např. uloží něco do souboru, pošlou něco po síti, atd. Chci dovolit více objektům reagovat na kliknutí tlačítka Takze jaka je situace, kdyz programuju to tlacitko. 13 13
Button – přes dědičnost SaveFileButton OpenFileButton ExecuteQueryButton Jedna moznost je dedicnost, ale ma nevyhody ShowResultsButton 14 14
Configuration Manager Button – přes observer Button File Manager Database Updater Zaridi se poslani zpravy. Nyni je spojeni objektu volne. Navic kdyz umim poslat zpravu file managerovi tak ji umim poslat I komukoliv jinemu. Configuration Manager 15 15
Button – dědičnost vs observer Pro každé tlačítko bude potřeba nová odvozená třída V ní se přepisuje nějaká metoda Reagující objekty s ní budou silně svázané Přidávání/odebírání reagujících objektů = změna tlačítka Změna reagujících = změna tlačítka Nelze hezky přestat reagovat na klikání tlačítka Nelze hezky po nějaké době začít reagovat na klikání tlačítka Nemá tyto problémy Jake jsou vyhody jednotlivych pristupu? 16 16
Observer – advanced - Change Manager Zapouzdření vazeb subject-observers Vhodné při složitějších vazbách (m:n, kaskády, zacyklení) Př: observery jsou notifikovány až potom, co všechny svázané subjecty změnily svůj stav Hlavní úkoly Mapování subjectu a jeho observerů (kdo koho) Definice aktualizační strategie (kdy a jak) Na žádost subjectu aktualizuje závislé observery 17 17
Observer – Change Manager Jednoduchý Change Manager Pouze projde seznam observerů a provede update Sofistikovaný Change Manager Používá složitější strategii Předchází nechtěným aktualizacím 18 18
Observer – příklady použití User interface aplikace/frameworky Oddělení dat od GUI Klient – server aplikace Notifikace klientů při změně na serveru Klienti si vyžádají údaje při notifikaci Konkrétní použití MVC (Model/View/Controller) - Model ≈ subject, View ≈ observer MFC - architektura Document/View java.util.Observable, java.util.Observer Java Swing - použití pro event management (EventListener, ...) Javafx, WinForms, javascript listenery, ... Java ObservableList, ListView, TableView, ... C#/WPF Uvnitř operačního systému Windows 19 19
Používání v C#/WPF – rozhraní pro objekty Jméno proměnné která se změnila Reference na Subject
Používání v C#/WPF – rozhraní pro objekty Oznámím změnu stavu Použít Setter!!!
O aktualizaci UI se stará WPF Používání v C#/WPF – rozhraní pro objekty O aktualizaci UI se stará WPF
WPF se stará o přidávání / odebírání položek v UI Používání v C#/WPF – rozhraní pro kolekce WPF se stará o přidávání / odebírání položek v UI
Observer - související vzory Mediator - ChangeManager jako prostředník mezi subjecty a observery Často implementovaný jako Singleton 24 24