Observer Struktura -každodenní použití -základní struktura -vlastnosti -implementace -možnosti v C#/WPF 1 1 1 1
NV Observer – idea 11° C 11:01 Subject (Meteostanice) Observer (server)r 12° C 11:02 11° C 11:05 2
- + NV Observer – idea Station Server .Attach(Server) .Update(12° C). Subject + 11° C ... 12° C ... Observer Observer je o propojení dvou druhů objektů – subject a observer - 1. Observer se připojí - Attach(), očekává informace 2. Subject informuje observera o změnách – Update(…) 3. Observer se odpojí - Detach() Station .Detach(Server) 3 3
NV Observer – definice Návrhový vzor Observer Observerr Vazba 1:N Subject : Observeři Subject notifikuje čekající observery o změnách Observeři se za běhu přidávají/odebírají ze subjectu Observerr foreach (server in Servers) server.Update(12° C) Observerr Subject Observerr
NV Observer – struktura Subject (Publisher, Observable) 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
Jak observer získá stav subjectu Push model Pull model Server.Update(data) Station.GetData() Server.Update(data) Station.GetData() Server.Update(data) Station.GetData() Subject Subject Update(data) Observer1r Update() Observer1r GetState() Observer2r Observer2r Update(data) Update() GetState()
Push / pull, výhody a nevýhody Push model Pull model Observer.Update(data) Subject.GetData() Observer zrovna nemusí potřebovat data – nevýhoda v síťové komunikaci Menší komunikační režie – výhoda v síťové komunikaci Vhodné, pokud každý observer potřebuje všechna data Observer si po updatu sám získá data od subjectu podle potřeby Pokud observer data potřebuje, více komunikace než push
C#, Programování II Subject Attach Detach push - potencialne neefektivni, obzvlast pri slozitejsich datech Attach Detach 8 8 8 8
NV Observer – pozorování Rozdělení zodpovědnosti - odlehčení funkcionality, lépe pochopitelné Znovupoužitelnost chování Redukuje závislosti (Decoupling / loose coupling) 9 9 9 9
NV Observer – detaily implementace Více sledovaných subjektů Observer neví, který subjekt update vyvolal Subjekt se předá jako argument do Update() Řešení notifikace Ve všech funkcích měnících stav Neefektivní, když měním model s mnoha subjecty, stačí update na konci 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, komplikované 10 10 10 10
Kliknuti = Co me zajima (aspekt) NV Observer – detaily implementace Sledování pouze specifických změn Observer v attach specifikuje, jaký druh změn jej zajímá button.addEventListener("click", function() { /* … */ } ); Přidání informace o druhu změny jako parametr update Enum NotifyCollectionChangedAction Add, Remove, Replace, Move, Reset Subjecty pro různé změny Button – Click, MouseEnter, MouseLeave, … Button = subject Kliknuti = Co me zajima (aspekt) Funkce = observer push - potencialne neefektivni, obzvlast pri slozitejsich datech 11 11 11 11
NV Observer – co nedělat Cykly A observer B, B observer A, při updatu mění stav Memory leaky Observer neudělá detach Závislost na pořadí updatu observerů Nespoléhat se na update předchozího observera před mým updatem – první observer A upraví vlasnost, kterou používá observer B => nečitelný běh programu skrytý v sérii updatů (ani mi nic nezaručuje, že pořadí existuje)
Observer – rozšíření - 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 13 13 13 13
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 14 14 14 14
NV Observer – příklady použití Aplikace s uživatelským rozhraním 1. event listenery (příklad s tlačítkem), 2. modifikace modelu -> update UI C# INotifyPropertyChange v GUI frameworcích (WPF, XamarinForms, …) Klient – server aplikace Notifikace klientů při změně na serveru Klienti si vyžádají údaje při notifikaci Konkrétní použití JavaScript, Java – Event listeners C# - Eventy a GUI ReactiveExtensions (RX) - JS, C#, C++, Java 15 15 15 15
C# event
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. 17 17 17 17
Button – přes dědičnost SaveFileButton OpenFileButton ExecuteQueryButton Jedna moznost je dedicnost, ale ma nevyhody ShowResultsButton 18 18 18 18
Configuration Manager Button – přes observer Click += (...) { /* FileManagerImpl */ }; Button File Manager Database Updater Configuration Manager Zaridi se poslani zpravy. Nyni je spojeni objektu volne. Navic kdyz umim poslat zpravu file managerovi tak ji umim poslat I komukoliv jinemu. 19 19 19 19
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? 20 20 20 20
Observer – 2 využití v GUI View je observer (změna modelu => změna view) Model je subject Prezentační vrstva Aplikační vrstva Takze jaka je situace, kdyz programuju to tlacitko. Click += (...) { /* FileManagerImpl */ }; 21 21 21 21
Observer – update view přes model 42 "B" "B" 42 66 "B" 66
Jméno membera (StringValue, ...) Base class pro subject Jméno membera (StringValue, ...) Subject Observer
WPF - INotifyPropertyChanged "B" Představa o bindingu Oznámím změnu stavu Použít Setter!!! WPF se stará o UI update "B" 24
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 25
Event Channel je jednou z variant vzoru publisher-subscriber pro distribuované systémy zpřetrhává závislosti mezi publisherem (těch může být i více) a subscribery event channel umístěn mezi publishery a subscribery vůči publisherovi se chová jako subscriber a naopak proxy umožňují maskovat skutečnou existenci všech tří druhů komponent v různých procesech může být obohacen o buffer, filtry, zřetězen s dalšími kanály 26 26
Observer - související vzory Mediator - ChangeManager jako prostředník mezi subjecty a observery Model-View-Controller Model-View-Presenter Model-View-ViewModel 27 27 27 27
Observer – výhody a nevýhody Loose-coupling Snadný přístup k informacím, kvůli kterým není třeba měnit Subject Nevýhody I malá změna Subjectu může stát hodně času (vlna změn) a tento čas může být těžké odhadnout. Downcasty Mohou vznikat race conditions 28 28 28 28