Decorator Radek Zikmund NPRG024, LS 2016/17.

Slides:



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

Seminář C++ 5. cvičení Dědičnost Ing. Jan Mikulka.
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.
Pole, ukazatele a odkazy
Ú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.
Singleton 1 1.
● 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
Proč programovat v LS objektově Jiří Krákora, Alliance Healthcare.
Adapter. Adapter – pojem Součástka navržená k propojení dvou „nekompatibilních“ zařízení Definice slova podle Cambridge Advanced Learner's Dictionary:
Objektové programování
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.
Facade [f ə ˈ s ɑː d]f ə ˈ s ɑː d. Facade Před: Po:
Composite [kompozit, ne kompozajt]. Composite Výslovnost  kompozit, ne kompozajt Účel  Popisuje, jak postavit hierarchii tříd složenou ze dvou druhů.
6. cvičení Polymorfismus
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í.
Algoritmizace a programování Objektově orientované programování - 16 Mgr. Josef Nožička IKT Algoritmizace a programování
Návrhový vzor Factory v JAVA API Martin Kot Katedra informatiky VŠB – Technická univerzita Ostrava
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
Návrh a tvorba WWW Přednáška 5 Úvod do jazyka PHP.
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.
Metodika objektového přístupu při tvorbě překladačů. Marek Běhálek Informatika a aplikovaná matematika FEI VŠB-TU Ostrava.
Principy OOP Objektově orientované programování vychá-zí ze třech základních principů (rysů): zapouzdření (encapsulation) dědičnost (inheritance) polymorfismus.
STRING A UKAZATELE. Co to je řetězec? Řetězec v Javě je samostatný objekt. Je konstantní, co znamená, že jednou vytvořený řetězec nelze změnit. Chceme-li.
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...
Pokročilé programování v C++ (část B)
Jazyk C A0B36PRI - PROGRAMOVÁNÍ Část II.
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í.
Visitor. Visitor - motivace Existující struktura typů Unit Character Main Hero Monster Environment Wall Magic Wall Stone Tree Mnoho nezávislých operací.
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.
Proxy. Popis  Klient má přístup k nějakému objektu  Potřebujeme tento přístup ošetřit, aniž bychom přidělali klientovi práci Kontrola přístupu Vzdálený.
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ř.
Uživatelská rozhraní Uživatelská rozhraní. knihovna Qt Trolltech (1994) v Oslu (Norsko) vytváří grafické uživatelské rozhraní (GUI) pro C++ multi-platformová.
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(); //
Proxy. Proxy poskytuje bariéru mezi klientem a reálnou implementací.
NÁZEV ŠKOLY: S0Š Net Office, spol. s r.o., Orlová-Lutyně AUTOR: Ing. Adéla Tomalová NÁZEV: Podpora výuky v technických oborech TEMA: Objektově orientované.
Praha & EU: Investujeme do vaší budoucnosti Evropský sociální fond Gymnázium, Praha 10, Voděradská 2 Projekt OBZORY MVC vs MVP.
SOLID principy v OOP návrhu
Y36PJC Programování v jazyce C/C++
Úvod do C# - OOP Jaroslav BURDYS 4IT.
Y36PJC Programování v jazyce C/C++
State 1.
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.
C# přehled vlastností.
ZAL – 7. cvičení 2016.
Decorator.
Monitor Object 1.
Proxy 1.
Adapter
Composite “Spojuj a panuj”.
Bridge.
Návrhový vzor Prototype.
Transkript prezentace:

Decorator Radek Zikmund NPRG024, LS 2016/17

Motivační příklad GUI Toolkit

Motivační příklad – GUI Toolkit Několik GUI prvků, několik možností dekorace posuvník – horní / spodní rámeček (různé šířky) Soustředíme se zatím jenom na TextView 3

Motivační příklad – GUI Toolkit GUI Toolkit obsahuje komponentu TextView prosté zobrazení textu Chceme instance této komponenty „dekorovat“ přidat posuvník přidat rámeček apod. Hodilo by se přitom: mít k dispozici také původní TextView bez dekorací kombinovat vlastnosti mezi sebou posuvník + rámeček přidávat některé vlastnosti vícenásobně dvojitý rámeček přidávat/odebírat konkrétní vlastnosti za běhu „vrstevnatá struktura“, Možná umět prohazovat vrstvy => posuvník uvnitř, nebo vně rámečku 4

Motivační příklad – GUI Toolkit 1. pokus o řešení: „supertřída“ obsahuje stavy (flagy) pro všechny možné dekorace vykreslovací metoda kontroluje přítomnost jednotlivých dekorací class TextView { private bool isBordered; // Is TextView bordered? private int borderWidth; // Used only by bordered TextViews. private bool isScrollable; // Is TextView scrollable? private int scrollBarPosition; // Used only by scrollable TextViews. // ... public void Draw() /* Main drawing logic here. */ if (isBordered) /* Border drawing logic here. */ } if (isScrollable) /* Scrollbar drawing logic here. */ 5

Motivační příklad – GUI Toolkit 1. pokus o řešení: „supertřída“ můžeme instancím přidávat/odebírat vlastnosti za běhu  nemusíme dekorovat vůbec  netřeba rozlišovat mezi obyčejnou a dekorovanou instancí  můžeme kombinovat vlastnosti  nemůžeme jednu vlastnost použít vícekrát  instance ví, že je dekorována  silně neflexibilní řešení    nerozšiřitelné bez modifikace TextView  Každou třídu musíme modifikovat zvlášť   TextView Button Label Grid Panel … ----- Meeting Notes (3/22/14 23:13) ----- Je to ošklivé Problém více odekorovaných tříd lze vyřešit společným předkem přesto však problémové Problém – horizontální a vertikální posuvník duplikace kódu Nemožnost si zvolit pořadí dekorování 2. Návrh: využít nějakou formu dědičnosti 6

Motivační příklad – GUI Toolkit 2. pokus o řešení: dědičnost bázová třída – TextView odvozené – BorderedTextView, ScrollableTextView, BorderedScrollableTextView class TextView { // ... fields and other necessary textview logic public virtual void Draw() { /*...*/ } } class BorderedTextView : TextView { // ... border-specific data and logic public override void Draw() { /*...*/ } class ScrollableTextView : TextView { // ... scrolling-specific data and logic class BorderedScrollableTextView : ScrollableTextView { // ... border-specific data and logic, probably copied from BorderedTextView 7

Motivační příklad – GUI Toolkit 2. pokus o řešení: dědičnost statické Nemožno měnit vlastnosti instance za běhu  pro každou kombinaci vlastností je třeba vytvořit novou třídu Stále si nemůžeme libovolně zvolit kombinaci/pořadí   BorderedScrollableBorderedTextView ...  vede k explozi tříd (n vlastností → 2n tříd)    podstatně zvyšuje komplexitu systému   Měnit vlastnosti za běhu znamená vytvořit nový objekt, překopírovat data a vyměnit je Co s referencemi na původní instanci? Dokážu je všechny opravit? Vícenásobná dědičnost v C++ SPOLEČNÝ PŘEDEK TextView!!! překrytí názvů? nedá se to udělat líp? Návrat k původní vrstevnaté myšlence 8

Motivační příklad – GUI Toolkit 3. Návrat k původní myšlence vrstev Delegace vykreslování rámečku/posuvníku na jiný objekt Myšlenka: Oddělit jednotlivé dekorace od původního objektu Orámečkovaný textview má dvě části: textview a rámeček Rámeček si bude držet referenci na textview, který dekoruje Nový objekt se bude starat jenom o vykreslení rámečku / posuvníku, vykreslení samotného textview nechá na textview samotném 9

Motivační příklad – GUI Toolkit 3. pokus o řešení: Decorator Společný (abstraktní) předek – def. interface pro kreslení Konkrétní vizuální komponenta Reference na dekorovaný objekt Delegace vykreslování na dekorovaný objekt Abstraktní dekorátor Konkrétní dekorátory vyjma delegace implementují navíc své vlastní vykreslování Konkrétní dekorátor 10

Motivační příklad – GUI Toolkit 3. pokus o řešení: Decorator public interface IVisualComponent { void Draw(); } class TextView : IVisualComponent public override void Draw() {  // draw window // ... abstract class Decorator : IVisualComponent  protected IVisualComponent vc;  // decorated component public Decorator(IVisualComponent vc) { this.vc = vc; public virtual void Draw() { vc.draw();           //delegation class ScrollDecorator : Decorator { public ScrollDecorator(IVisualComponent vc) : base(vc) { } public override void Draw()  { base.Draw();     // draw component DrawScrollBar(); } private void DrawScrollBar() { /*...*/ } // scrolling logic implementation // ... class BorderDecorator : Decorator { public BorderDecorator(IVisualComponent vc) drawScrollBar(); private void DrawBorder() { /*...*/ } 11

Motivační příklad – GUI Toolkit 3. pokus o řešení: Decorator dekorátory přidávají jednotlivé vlastnosti (dekorace) můžeme instancím přidávat/odebírat vlastnosti za běhu  máme k dispozici i obyčejný TextView  dekorace jsou navzájem nezávislé  lze je libovolně kombinovat  lze je používat i vícekrát  je to transparentní  z hlediska klienta není rozdíl mezi obyčejným a dekorovaným TextView TextView o dekoracích vůbec neví VisualComponent licenseTextView = new BorderDecorator( new ScrollDecorator( new TextView())); // somewhere else: licenseTextView.Draw(); Pro odebírání vlastností potřebujeme podporu v rozhranní! 12

std::reverse_iterator Motivační příklad std::reverse_iterator

Motivační příklad – std::reverse_iterator Příklad minimalistické implementace template <typename Iter> class reverse_iterator : public std::iterator< typename Iter::iterator_category, typename Iter::value_type, typename Iter::difference_type, typename Iter::pointer, typename Iter::reference> { private: Iter current; // decorated iterator public: explicit reverse_iterator(Iter&& p) : current{std::forward<Iter>(p)} {} void operator=(const reverse_iterator& other) { current = other.current; } typename Iter::reference operator*() const { auto tmp = current; return *--tmp; reverse_iterator& operator++() { --current; return *this; bool operator!=(const reverse_iterator& other) const { return current != other.current; }; template <typename Iter> typename reverse_iterator<Iter> make_reverse(Iter&& i) { return reverse_iterator<Iter>{std::forward<Iter>(i)}; } void print_elements(Iter begin, Iter end) { for (; begin != end; ++begin) std::cout << *begin << " "; int main(int argc, char* argv[]) { std::vector<int> v = { 1,2,3,4,5,6,7,8,9,10 }; print_elements( make_reverse(v.end()), make_reverse(v.begin())); std::cout << std::endl; 14

Decorator – shrnutí Strukturální vzor 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 objektů před dědičností Delegace volání na dekorovaný objekt + vlastní přidaná funkcionalita vlastní přidané chování může být před i za delegovaným voláním 15

Decorator – struktura a účastníci Component – def. rozhraní pro objekty, které je možné dynamicky rozšiřovat ConcreteComponent – def. objekt, který je možné dynamicky rozšířit Decorator – abstraktní předek všech dekorátorů obsahuje refenci na objekt, který dekoruje všechna volání deleguje na dekorovaný objekt ConcreteDecorator – přidává dodatečné chování komponentě 16

Decorator – implementace Použití typicky pomocí řetězení konstruktorů: Rozhraní dekorátoru musí být shodné s rozhraním dekorovaného objektu dědění od společného předka nebo implementace společného interface Abstraktní dekorátor lze vynechat za předpokladu, že potřebujeme přidat pouze jediné rozšíření často v případě, kdy potřebujeme rozšířit existující kód delegování na komponentu se pak děje přímo v tomto jediném dekorátoru Společný předek (Component) by měl zůstat odlehčený definice rozhraní, nikoli uložení dat jinak hrozí, že dekorátory budou příliš těžkotonážní Component c = new ConcreteDecoratorA( new ConcreteDecoratorB( new ConcreteComponent(...))); c.Operation(); 17

Decorator – výhody a nevýhody vyšší flexibilita pro přidávání funkcionality než při statickém dědění vlastnosti lze přidávat/odebírat za běhu aplikace několikanásobné použití stejné dekorace transparentnost není třeba předvídat všechny potřeby klienta jednoduché inkrementální přidávání funkcionality Nevýhody komponenta a její dekorovaná verze nejsou identické dekorátor se chová jako transparentní zapouzdření při použití dekorátorů nespoléhat na identitu objektů! mnoho podobných (malých) objektů potenciálně horší orientace v kódu dlouhé řetězce dekorátorů mohou mít dopad na výkon 18

Reálně využívané Decoratory Grafické toolkity Java Swing System.Windows.Controls Čtení vstupu, zapisování výstupu System.IO.Stream java.io Component ConcreteComponent Decorator DataInputStream dis = new DataInputStream( new GzipInputStream( new BufferedInputStream( new FileInputStream("file.gz")))); dis.Read(...); ConcreteDecorator 19

Související vzory Adapter Composite Strategy Decorator mění pouze chování objektu, ne jeho rozhraní Adapter dá objektu zcela nové rozhraní Composite Decorator lze technicky vnímat jak zdegenerovaný Composite s jedinou komponentou Decorator přidává dodatečné chování není určen pro agregaci objektů Strategy Decorator umožňuje měnit skin (povrch, kůži...) objektu v zásadě obaluje nějaký objekt a mění při tom jeho chování zatímco Strategy umožňuje měnit „vnitřnosti“ (guts) objektu komponenta ve Strategy ví o možných extenzích, u Decoratoru nikoli: 20

Dotazy?

Děkuji za pozornost 