Visitor. Visitor - motivace Existující struktura typů Unit Character Main Hero Monster Environment Wall Magic Wall Stone Tree Mnoho nezávislých operací.

Slides:



Advertisements
Podobné prezentace
(instance konkrétní třídy)
Advertisements

Funkce Připomeňme si program pro výpočet faktoriálu:
Proxy. Definice  zástupce nebo náhradník za dotyčný objekt  proxy i zastoupený objekt dědí od stejného interfacu  proxy kontroluje přístup k objektu.
ÚVOD DO CPP 7 Dědičnost - pokračování
PJV151 Vnořené a vnitřní členy mohou být členy tříd a interfejsů. Je-li X obalem Y a Y je obalem Z, pak Z získá jméno X$Y$Z - kompilací vzniknou classy.
Polymorfismus Dědičnost
● SWIG - Simplified Wrapper and Interface Generator ● + google a diskusní fóra ● nástroj zjednodušující (a sjednocující)
Čtvrté cvičení Objektové programování Objektový model v Javě
J a v a Začínáme programovat Lucie Žoltá metody, objekty, konstruktor.
Chain of responsibility Martin Malý prezentace na předmět Návrhové vzory (PRG024) na MFF UK
State. State – kontext a problém Kontext  chování objektu má záviset na jeho stavu, který se typicky mění za běhu Neflexibilní řešení  metody obsahují.
Páté cvičení Dědičnost Interface Abstarktní třídy a metody
PB161 Jmenné prostory, I/O proudy PB161 | Jmenné prostory, IO proudy PB161 – Programování v jazyce C++ Objektově Orientované Programování.
Adapter. Adapter – pojem Součástka navržená k propojení dvou „nekompatibilních“ zařízení Definice slova podle Cambridge Advanced Learner's Dictionary:
C# - Exceptions (výjimky)
Objektové programování
Sémantická analýza Jakub Yaghob
Seminář C cvičení Obsluha výjimek Ing. Jan Mikulka.
Strategy. Strategy – „All-in-1“ na začátek class AStrategy { public: virtual void Algorithm()=0; protected: AStrategy(); }; class SpecificStrategy: public.
Composite [kompozit, ne kompozajt]. Composite Výslovnost  kompozit, ne kompozajt Účel  Popisuje, jak postavit hierarchii tříd složenou ze dvou druhů.
Dependency injection Předávání závislostí Petr Kalivoda
6. cvičení Polymorfismus
PB161 Právo friend, přetěžování operátorů, přetypování PB161 | Friend, operátory PB161 – Programování v jazyce C++ Objektově Orientované Programování.
Memento. Obnovení operačního systému ( Windows | Linux...) Všichni víme, co jsou transekce v databázi Memento – zálohování databáze.
KIV/PPA1 cvičení 8 Cvičící: Pavel Bžoch. Osnova cvičení Objekty v Javě Třída Konstruktor Metody Metody a proměnné třídy x instance Program sestávající.
OSNOVA: a) Úvod do OOPb) Třídy bez metod c) Třídy s metodamid) Konstruktory a destruktory e) Metody constf) Knihovní třídy g) Třídy ve tříděh) Přetížení.
PB161 Principy OOP - rozhraní, dědičnost PB161 | Principy OOP - Dědičnost, rozhraní
C# - předávání parametrů Centrum pro virtuální a moderní metody a formy vzdělávání na Obchodní akademii T.G. Masaryka, Kostelec nad Orlicí.
IB111 Programování a algoritmizace
Dědičnost - inheritance dědičnost je jednou z forem znovupoužitelnosti dědičnost je jednou z forem znovupoužitelnosti B A Třída A je předkem třídy B Třída.
12/04/20151 Kolekce (1) Kolekce (collection) představují standardní datové struktury (seskupení) prvků (objektů) Jsou definovány ve jmenném prostoru System.Collections.
OSNOVA: a)Funkce – úvod b) Hlavičky funkcí c) Rekurze funkcí d)Knihovny funkcí e)Příklady Jiří Šebesta Ústav radioelektroniky, FEKT VUT v Brně Počítače.
Metodika objektového přístupu při tvorbě překladačů. Marek Běhálek Informatika a aplikovaná matematika FEI VŠB-TU Ostrava.
Šesté cvičení Výjimky Balíky.
Principy OOP Objektově orientované programování vychá-zí ze třech základních principů (rysů): zapouzdření (encapsulation) dědičnost (inheritance) polymorfismus.
Decorator. Rozšiřuje objekty o dodatečné chování  rozšiřuje konkrétní objekty, ne třídy  rozšiřuje objekt dynamicky, tj. za běhu Upřednostňuje kompozici.
Vzor na všechno. Vzor – úvod Problém .. Příklad: widgety .. Jak na to? .. Známý také jako...
FEL Komunikátor. Memory Leak program konsumuje operační paměť, kterou neumožňuje uvolnit o uvolnění paměti stará Garbage Collector ▫plně v režii Java.
Pokročilé programování v C++ (část B)
Jazyk C A0B36PRI - PROGRAMOVÁNÍ Část II.
Kam se ubírá jazyk C#? Dr. Ing. Dalibor Kačmář Academic Developer Evangelist Developer & Platform Evangelist Group Microsoft Czech & Slovakia Anders Hejlsberg.
Service layer. Service layer – úvod Problém  Vytvoření API aplikace  Odstínění bussiness logiky a transakčního chování od zbytku aplikace  Kam s aplikační.
Observer Martin Dráb Návrhové vzory, Co to je?  Definuje závislost 1:N mezi objekty  Závislé objekty jsou informovány o změně stavu  Konzistentní.
XSLT překladač Marek Běhálek Informatika a aplikovaná matematika FEI VŠB-TU Ostrava.
Strategy. Motivace Různé algoritmy pro stejnou akci Hromada kódu v mnoha podmínkách Důsledky  Komplexnost  Špatná čitelnost  Těžká správa kódu  Těžka.
Iterator Iterator – Problém struct Item { int _value; Item * _next; Item( int value, Item * next ) : _value( value ), _next( next ) { } }; void Print(
Template Method. Motivační příklad – reálný svět Čaj 1) Uvař vodu 2) Dej do hrnku sáček čaje 3) Zalij hrnek 4) Přisyp cukr a vymačkej citrón Káva 1) Uvař.
Perzistence XML dat Kamil Toman
Composite “ Spojuj a panuj ”. Zakladní vlastnosti Výslovnost  kompozit, ne kompozajt Účel  Popisuje, jak postavit strukturované hierarchie tříd, v níž.
Iterator. C historie int * rand_numbers(int n) { int *numbers = malloc(n * sizeof(int)); int *it = numbers; while (it < numbers + n) *it++ = rand(); //
PROGRAMOVÁNÍ 3ITA,3ITB Jaroslav Burdys Hlavní zdroj:
Praha & EU: Investujeme do vaší budoucnosti Evropský sociální fond Gymnázium, Praha 10, Voděradská 2 Projekt OBZORY Datové typy a operátory Základní programové.
Strategy. Motivace Ze života - jak to taky může vypadat (R): source("../algorithms/HOCForLOCF.R") source("../algorithms/HOCForLOCFv2.R") source("../MILP/MILP.R")
SOLID principy v OOP návrhu
Úvod do C# - OOP Jaroslav BURDYS 4IT.
Mediator Několik slov o překladu slova do češtiny (prostředník, zprostředkovatel), vyzdvihnutí počeštěného slova mediátor. 1 1.
Decorator Radek Zikmund NPRG024, LS 2016/17.
NÁZEV ŠKOLY: Střední odborná škola Net Office, spol. s r. o
Návrhový vzor Flyweight
Abstract Factory.
Strategy „Definujte rodinu algoritmů, zapouzdřuje je aby byly vzájemně zaměnitelné. Strategie umožňuje, aby se algoritmus nebyl závislý na klientech, kteří.
Bridge.
Visitor 1 1.
C# přehled vlastností.
Decorator.
Monitor Object 1.
Proxy 1.
Composite “Spojuj a panuj”.
Bridge.
Návrhový vzor Prototype.
Transkript prezentace:

Visitor

Visitor - motivace Existující struktura typů Unit Character Main Hero Monster Environment Wall Magic Wall Stone Tree Mnoho nezávislých operací Draw Collision Animation

Visitor - motivace Každá dvojice typ a operace má jiný kód Main Hero, Draw Wall, Collision Stone, Collision... Implementace operace v jednom modulu DrawHero DrawWall DrawStone... Předpokládáme stabilní struktura typů se společným předkem přibývající operace

Visitor – Double Dispatch Intermezzo Single Dispatch  C++, C#, Java  Jméno funkce + odkaz na objekt  Podpora v jazyce pomocí virtuálních funkcí Double Dispatch  CLOS, Haskell, Dylan  Jméno funkce + odkaz na objekt 1 + odkaz na objekt 2  příklad: výpočet obsahu průniku dvou geometrických obrazců  Možné řešení:  pomocí vzoru Visitor  hrubou silou  šablony + typelisty  type_info + std::map ...

Visitor - motivace Možné řešení bez visitoru - operace v třídách Výhody  jednoduché  intuitivní Nevýhody  pracné přidávání metod  funkčnost rozházená po třídách  nezachovává se stav MagicWall draw() collision() animation()... Environment draw() collision() animation()... Wall draw() collision() animation()... Stone draw() collision() animation()... …… Client

Visitor - motivace Možné řešení bez visitoru - špagetový kód Výhody  kód na jednom místě Nevýhody  nepřehledný, opakující se kód  mnoho switch / if-else-if bloků pomalé, snadné zapomenout na nějaký typ void printStatistics(List elements){ foreach (Unit e in elements) { if (e is Wall) { //... } else if (e is MagicWall) { //... } else if (e is Stone) { //... }

Visitor - motivace Řešení s použitím Visitoru Environment accept(Visitor v) Wall accept(Visitor v) MagicWall accept(Visitor v) Stone accept(Visitor v) v.visitMagicWall(this);v.visitStone(this); Object structure (Traverser) v.visitWall(this); Visitor visitWall(Wall e) visitMagicWall(MagicWall e) visitStone(Stone e) DrawVisitor visitWall(Wall e) visitMagicWall(MagicWall e) visitStone(Stone e) CollisionVisitor visitWall(Wall e) visitMagicWall(MagicWall e) visitStone(Stone e) Potomci Visitora jednoduše přidávají další operace bez nutnosti změny v typech struktury typů. Každý uzel v metodě accept zavolá Visitora „na návštěvu“

Visitor Visitor obecně Visitor visitA(ElementA) visitB(ElementB) Visitor1 visitA(ElementA) visitB(ElementB) Visitor2 visitA(ElementA) visitB(ElementB) AbstractElement accept(Visitor) ElementA accept(Visitor) ElementB accept(Visitor) v.visitA(this);v.visitB(this); Object structure (Traverser) Client

Visitor - účastníci Přehled účastníků  Visitor interface (nebo abstraktní třída), který musí implementovat konkrétní Visitory definuje metody visit pro všechny typy elementů  může využívat i overloading funkcí: Visit( ElementA& ); Visit( ElementB& );  Visitor1, Visitor2 konkrétní Visitory (implementují rozhraní Visitor) přidávají novou funkcionalitu do existující struktury  AbstractElement interface (nebo abstraktní třída) pro typy, které mohou být navštíveny Visitorem definuje abstraktní metodu accept  ElementA, ElementB konkrétní elementy odvozené od AbstractElement implementují metodu accept (uvnitř které pozve předaného Visitora na návštěvu)  Object structure (traverser) umí procházet strukturu elementů na každém elementu zavolá metodu accept

Visitor - vlastnosti Výhody  snadno přidám novou operaci na třídě stačí napsat nového Visitora není třeba měnit objekty hierarchie Visitory mohou být implementovány jako zásuvné moduly  zapouzdření souvisejících operací Visitor skrývá specifika algoritmu  udržování kontextu při průchodu strukturou objektů uvnitř Visitoru Visitor může mít vnitřní stav (data)  nemusí se předávat parametrem, nebo v globálních hodnotách  vnitřní stav může ovlivnit prováděné operace

Visitor - důsledky a souvislosti Nevýhody  přidání nového typu objektu většinou znamená úpravu všech Visitorů nasazení při častěji měnící se struktuře je nevhodné  porušení zapouzdření objektů, nad nimiž se operuje Visitor může potřebovat pracovat s interním stavem  obtížné zavedení do hotového kódu  složitějsí kód explicitní získávání návratové hodnoty

Visitor – sekvenční diagram Sekvenční diagram

Visitor - procházení struktury Jakým způsobem lze procházet strukturu objektů visitorem? Kde bude kód umístěn:  klient více práce pro klienta klient má možnost plně řídit, koho Visitor navštíví  struktura rekurzivní volání metody accept na potomky při použití vzoru Composite  Iterator nelze použít, pokud objekty nemají společného předka kód na procházení je na jediném místě  Visitor elementy struktury nemusí mít společného předka komplexnější algoritmy průchodu strukturou duplikace kódu na procházení v každém Visitoru

Visitor – implementace C# interface IElement { void Accept(IVisitor visitor); } interface IVisitor { void Visit(IElement element); void Visit(Wall binary); void Visit(Stone value); void Visit(Map value); } vše zachytávající funkce společný interface class Wall:IElement { public readonly int Number;... public void Accept(IVisitor visitor) { visitor.Visit(this); } class Wall:IElement { public readonly int Number;... public void Accept(IVisitor visitor) { visitor.Visit(this); } accept na jednoduchém objektu class Map: IElement { public readonly char Operator; public readonly List staticObjects; public readonly List characters;... public void Accept(IVisitor visitor) { foreach(var e in this.staticObjects) { e.Accept(visitor); } foreach(var e in this.staticObjects) { e.Accept(visitor); } visitor.Visit(this); } class Map: IElement { public readonly char Operator; public readonly List staticObjects; public readonly List characters;... public void Accept(IVisitor visitor) { foreach(var e in this.staticObjects) { e.Accept(visitor); } foreach(var e in this.staticObjects) { e.Accept(visitor); } visitor.Visit(this); } accept na složeném objektu

Visitor – implementace C# class CollisionVisitor : IVisitor { private Hero hero; // whether hero collides private bool status; public void Visit(IElement element) { if(!(hero.x + hero.width < element.x || hero.x > element.x + element.width) || !(hero.y + hero.height < element.y || hero.y > element.y + element.height)){ status = false; } }... } class DrawVisitor : IVisitor { private Dictionary bitmaps; public void Visit(IElement element) { throw new Exception("Unknown object"); } public void Visit(Wall element) { if(!bitmaps.ContainsKey(element)) bitmaps[element] = LoadWallBitmap(); Window.Draw(this.bitmaps[element]); } public void Visit(Stone value) { if(!bitmaps.ContainsKey(element)) bitmaps[element] = LoadStoneBitmap() Window.Draw(this.bitmaps[element]); }... }

interface IVisitor { void Visit(IElement element); void Visit(Wall binary); void Visit(Stone value); void Visit(Map value); void Visit(BabaYagaMonster value); } Visitor – problém s rozšiřitelností Chtěli bychom přidat BabaYagaMonster

class DrawVisitor : IVisitor { private Dictionary bitmaps; public void Visit(IElement element) { throw new Exception("Unknown object"); } public void Visit(Wall element) { if(!bitmaps.ContainsKey(element)) bitmaps[element] = LoadWallBitmap(); Window.Draw(this.bitmaps[element]); } public void Visit(Stone value) { if(!bitmaps.ContainsKey(element)) bitmaps[element] = LoadStoneBitmap() Window.Draw(this.bitmaps[element]); } public void Visit(BabaYagaMonster value) { if(!bitmaps.ContainsKey(element)) bitmaps[element] = LoadBabaYagaBitmap() Window.Draw(this.bitmaps[element]); }... } interface IVisitor { void Visit(IElement element); void Visit(Wall binary); void Visit(Stone value); void Visit(Map value); void Visit(BabaYagaMonster value); } Visitor – problém s rozšiřitelností Chtěli bychom přidat BabaYagaMonster class CollisionVisitor : IVisitor { private Hero hero; // whether hero collides private bool status; public void Visit(IElement element) { if(!(hero.x + hero.width < element.x || hero.x > element.x + element.width) || !(hero.y + hero.height < element.y || hero.y > element.y + element.height)){ status = false; } public void Visit(BabaYagaMonster value) { // No implementatation }... }

Visitor – Double dispatch C#... IVisitor visitor = new ConcreteVisitor(); foreach(IElement el in elements) { visitor.Visit(el); } class ConcreteVisitor:IVisitor { void Visit(IElement w){... } void Visit(UnaryOperator w){... } interface IVisitor { void Visit(IElement w); } Řešení ?

Visitor – Double dispatch C#... IVisitor visitor = new ConcreteVisitor(); foreach(IElement el in elements) { visitor.Visit(el); } class ConcreteVisitor:IVisitor { void Visit(IElement w){... } void Visit(UnaryOperator w){... } interface IVisitor { void Visit(IElement w); } Řešení ? K výběru funkce dochází již za překladu!

Visitor – Double dispatch C#... IVisitor visitor = new ConcreteVisitor(); dynamic dispatchedVisitor=visitor; foreach(IElement el in elements) { dispatchedVisitor.Visit((dynamic) el); } class ConcreteVisitor:IVisitor { void Visit(IElement w){... } void Visit(UnaryOperator w){... } interface IVisitor { void Visit(IElement w); } Řešení !

Visitor – Double dispatch C#... IVisitor visitor = new ConcreteVisitor(); dynamic dispatchedVisitor=visitor; foreach(IElement el in elements) { dispatchedVisitor.Visit((dynamic) el); } class ConcreteVisitor:IVisitor { void Visit(IElement w){... } void Visit(UnaryOperator w){... } interface IVisitor { void Visit(IElement w); } Ale... Dynamické typování je výrazně pomalejší

Visitor - Shrnutí Používáme když  máme stabilní strukturu typů  chceme přidávat nezávislé funkce nad typy struktury Není vhodné když struktura typů není stabilní  přidání nového typu je pracné Výhody  přehledný kód  rozšiřitelnost funkcí nad typy  zapouzdření kontextu dané funkce Visitor částečně nahrazuje chybějící podporu Double Dispatch v jazycích jako jsou C++, C#, Java Obecná implementeace techniky Multi Dispatch se nazývá Multimethods

Visitor - použití v praxi Příklady  XML parsery (např. SAX) parser.parse(file, handler) startElement() endElement() character()  Stromové struktury visitNode visitLeaf  Překladače operace nad syntaktickým stromem