, Brno Připravil: David Procházka Návrhové vzory

Podobné dokumenty
1. prosince 2013, Brno Připravil: David Procházka

Návrhové vzory. Jakub Klemsa, Jan Legerský. 30. října Objektově orientované programování.

Semin aˇr Java N avrhov e vzory Radek Ko ˇc ı Fakulta informaˇcn ıch technologi ı VUT Duben 2008 Radek Koˇc ı Semin aˇr Java N avrhov e vzory 1/ 24

Semin aˇr Java N avrhov e vzory Radek Ko ˇc ı Fakulta informaˇcn ıch technologi ı VUT Duben 2009 Radek Koˇc ı Semin aˇr Java N avrhov e vzory 1/ 25

ČÁST 1. Zahřívací kolo. Co je a k čemu je návrhový vzor 33

Jazyk C# (seminář 3)

Generické programování

Bridge. Známý jako. Účel. Použitelnost. Handle/Body

OMO. 4 - Creational design patterns A. Singleton Simple Factory Factory Method Abstract Factory Prototype Builder IoC

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Chování konstruktorů a destruktorů při dědění

Jazyk C++ I. Šablony

Návrhové vzory OMO, LS 2014/2015

Programování v C++ 2, 8. cvičení

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

Programování v C++ 1, 5. cvičení

Jazyk C++ I. Šablony 2

20. Projekt Domácí mediotéka

State. Známý jako. Účel. Použitelnost. Stav, Object for States. umožňuje objektu měnit svoje chování v závislosti na stavu objekt mění svou třídu

Pokročilé programování v jazyce C pro chemiky (C3220) Pokročilá témata jazyka C++

<surface name="pozadi" file="obrazky/pozadi/pozadi.png"/> ****************************************************************************

1. Dědičnost a polymorfismus

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března

Více o konstruktorech a destruktorech

PŘETĚŽOVÁNÍ OPERÁTORŮ

24. listopadu 2013, Brno Připravil: David Procházka

IB111 Programování a algoritmizace. Objektově orientované programování (OOP)

Programování v C++ 1, 6. cvičení

KTE / ZPE Informační technologie

Quo vadis programování? Automatizace vyhodnocování studentských úloh

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Konstruktory a destruktory

Návrhové vzory Design Patterns

Programování v C++ VI

PB161 Programování v jazyce C++ Přednáška 7

Základy objektové orientace I. Únor 2010

PB161 Programování v jazyce C++ Přednáška 7

Připravil: David Procházka. Programovací jazyk C++

8 Třídy, objekty, metody, předávání argumentů metod

16. února 2015, Brno Připravil: David Procházka. Konstruktory a destruktory

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

specifikuje vytvářené objekty pomocí prototypické instance nový objekt vytváří kopírováním prototypu

návrhový vzor Singleton.

Výčtový typ strana 67

7. přednáška - třídy, objekty třídy objekty atributy tříd metody tříd

Využití OOP v praxi -- Knihovna PHP -- Interval.cz

TŘÍDY POKRAČOVÁNÍ. Události pokračování. Příklad. public delegate void ZmenaSouradnicEventHandler (object sender, EventArgs e);

PREPROCESOR POKRAČOVÁNÍ

Principy objektově orientovaného programování

10. března 2015, Brno Připravil: David Procházka. Programovací jazyk C++

NMIN201 Objektově orientované programování 1 / :36:09

Programování II. Polymorfismus

IoC/DI. Tomáš Herceg Microsoft MVP (ASP.NET)

Funkční objekty v C++.

IRAE 07/08 Přednáška č. 1

Třídy. Instance. Pokud tento program spustíme, vypíše následující. car1 má barvu Red. car2 má barvu Red. car1 má barvu Blue.

Abstract Factory úvod

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

Programování v C++ 3, 3. cvičení

Dalším příkladem může být například výstup dat na různá zařízení, souborů, grafických rozhraní, sítě atd.

Semin aˇr Java X Radek Koˇc ı Fakulta informaˇcn ıch technologi ı VUT Duben 2011 Radek Koˇc ı Semin aˇr Java N avrhov e vzory, Z asady...

Obsah přednášky 9. Skrývání informací. Skrývání informací. Zapouzdření. Skrývání informací. Základy programování (IZAPR, IZKPR) Přednáška 9

Abstraktní třída a rozhraní

NPRG031 Programování II 1 / :25:46

Vyřešené teoretické otázky do OOP ( )

Mnohotvarost (polymorfizmus)

IRAE 07/08 Přednáška č. 2. atr1 atr2. atr1 atr2 -33

Dědičnost. seskupování tříd do hierarchie. potomek získá všechny vlastnosti a metody. provádí se pomocí dvojtečky za názvem třídy.

Programování v C++ 2, 4. cvičení

Virtuální metody - polymorfizmus

C++ přetěžování funkcí a operátorů. Jan Hnilica Počítačové modelování 19

Seminář Java IV p.1/38

Dědičnost. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 23.března

Objekt. základní prvek v OOP. má vlastnosti. má metody. vznikne vytvoření nové instance definován pomocí třídy

Dědění, polymorfismus

PB161 Programování v jazyce C++ Přednáška 4

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

PB161 Programování v jazyce C++ Přednáška 8

Šablony, kontejnery a iterátory

Úvod do programování - Java. Cvičení č.4

Šablony, kontejnery a iterátory

Jazyk C# (seminář 6)

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Java a XML. 10/26/09 1/7 Java a XML

1. Programování proti rozhraní

typová konverze typová inference

přetížení operátorů (o)

Singleton obsah. Motivace Základní myšlenka Implementace Problémy. Dědičnost Obecná implementace Shrnutí. destrukce vícevláknovost

Algoritmizace a programování

Jazyk C++, některá rozšíření oproti C

Problém, jehož různé instance je třeba často řešit Tyto instance lze vyjádřit větami v jednoduchém jazyce

Pokročilé programování v jazyce C pro chemiky (C3220) Dědičnost tříd v C++

Kód, který se nebude často měnit

Jazyk C# (seminář 5)

Jazyk C++ I. Polymorfismus

Motivační příklad reálný svět. výroba (assembly line)

Jazyk C++ II. Šablony a implementace

Při studiu tohoto bloku se předpokládá, že student je zvládá základy programování v jazyce Java s využitím vývojového prostředí NetBeans.

Transkript:

7. 10. 2010, Brno Připravil: David Procházka Návrhové vzory Základy objektově orientovaného návrhu

Design Patterns NV (Design patterns) můžeme s nadsázkou označit za ntu, jak řešit určitý problém nejen při návrhu OO systému. Existuje 23 základních vzorů, od kterých se odvozují další. Vzorem může být jakékoliv řešení problému. NV byly poprvé popsány v knize Gama, Helm, Johnson, Vlissides: Design Patterns - Gang of Four

Jaká je ideální třída: jednoduchá 1. Tvořivé vzory: Jak skrýt implementaci objektů, aby nebylo nutné při jejich změně měnit systém. Jak správně navrhovat třídy, tvořit instance. 2. Strukturální změny: Snahou je zpřehlednit systém. Zabývají se propojením objektů. Jak propojení omezit nebo předejít změnám prop. 3. Vzory chování: Zapouzdřují určité procesy prováděné v systému.

Vzory spolu souvisí

Přepravka (Crate / Messenger) Prvním jednoduchým nástrojem je přepravka. Jedná se o konteiner, který je předáván metodám a ty do něj umisťují data. Výhodou je, že metody si nemusí předávat data navzájem velké množství parametrů, ale jen jednu přepravku. Některé jazyky nepodporují předávání hodnotou i odkazem a pokud je potřeba z metody vracet více hodnot. Navíc vracení více hodnot pomocí odkazů v parametrech je někdy považováno na nevhodné.

Přepravka class Pozice{ public: int x; int y; }; class Rozmer{ public: int sirka; int vyska; };

Přepravka Atributy mohou být veřejné, není dobré "recyklovat" přepravky (rozměr i pozice mají 2 int souřadnice), přepravka může být pro přenos mezi metodami nebo interní pro uchování skupiny hodnot pohromadě (metoda pracující s úkoly si je potřebuje sesbírat, než je zpracuje).

Továrna (Factory) Problém: V průběhu života systému se často stane, že musím změnit konstruktor určité třídy (změní se počet nebo typy parametrů, atp.). Důsledek: Musím procházet celý program, abych našel, kde všude se instance dané třídy vytváří. Řešení: Zapouzdřím vytváření objektů do speciální "továrny". Pokud budu potřebovat instanci dané třídy, pouze zavolám metodu továrny a ta mi instanci vrátí.

Továrna class Shape{ public: // rozhrani pro vsechny potomky virtual void draw() = 0; virtual void erase() = 0; }; // factory je metoda tridy static Shape* factory(string type);

Továrna class Circle : public Shape { public: void draw() { cout << "Circle::draw"; } }; void erase() { cout << "Circle::erase"; } // to stejne pro ctverec

Továrna Shape* Shape::factory(string type){ if (type == "Circle") return new Circle(); else return new Square(); }

Továrna int main () { Shape* ctverecek=shape::factory("square"); ctverecek->draw(); } delete ctverecek; return 0;

Abstraktní továrna (Abstract fac.) V předchozím příkladu byla tovární metoda součástí abstraktní třídy, existují i varianty, kdy je definována v samostatné třídě. Důvodem je možnost vytvářet potomky továren. Problém: Máme hru Doom, chceme aby ve hře byly postavy Voják, Mutant, SuperMutant. Navíc chceme aby pro lepší hratelnost existovali od každé z postav dvě varianty: hloupý a chytrý. Jak zajistit jednoduchou výrobu těchto postav a jak zajistit, aby vždy vznikaly pouze postavy jednoho typu.

Schéma potvor

Abstraktní továrna - vzor class AbstraktniTovarnaNepritele{ public: virtual Vojak* vytvorvojaka() = 0; virtual Mutant* vytvormutanta() = 0; virtual SuperMutant* vytvorsupermut() = 0; };

Abstraktní továrna - implementace class MalaObtiznost : public AbstraktniTovarnaNepritele{ public: Vojak* vytvorvojaka() { return new HloupyVojak() } Mutant* vytvormutanta() { return new HloupyMutant() } SuperMutant* vytvorsupermutant() { return new HloupySuperMutant() } };

Abstraktní továrna - implementace class VelkaObtiznost : public AbstraktniTovarnaNepritele{ public: Vojak* vytvorvojaka() { return new ChytryVojak() } Mutant* vytvormutanta() { return new ChytryMutant() } SuperMutant* vytvorsupermutant() { return new ChytrySuperMutant() } };

Abstraktní továrna - použití class HerniAplikace{ public: void zvolobtiznost(string obtiznost){ if (obtiznost == "mala"){ tovarna = new MalaObtiznost(); } else { tovarna = new VelkaObtiznost(); } } private: AbstraktniTovarnaNepritele* tovarna;...

Co jsme získali Logika vytváření příšer je skryta uvnitř továrny. Továrna sama zajistí, aby se daly vytvořit jen příšery zvoleného typu.

Jedináček (Singelton) Občas je nutné zajistit, aby se od dané třídy vytvořila vždy pouze jedna instace. Např. metoda na práci s tiskárnou, obrazovkou, atp. Pokud více objektů potřebuje s instancí této třídy pracovat, musí sdílet pouze jednou instanci.

Jedináček - struktura class Singleton{ public: static Singleton* vratinstanci(){ if (!uinstance) uinstance = new Singleton; return uinstance; }... metody... private: static Singleton* uinstance; Singleton(){}; Singleton(const Singleton&){}; };

Jedináček - použití Singleton* Singleton::uInstance = 0; int main () { Singleton* instance = Singleton::vratInstanci();... volani metod... return 0; }

Jedináček - použití Skrytím konstruktorů jsme zabránili ručnímu vytváření nových instancí i potenciálnu kopírování existující instance. To je dovoleno jen metodám třídy Singelton. Instance se vytvoří při prvním použití (daní je krátký test). Problém je, jak Singelton zrušit a řada dalších "drobností" (viz Alexandrescu, Moderní programování v C++, str. 151).

Jednostavový objekt (Monostate) Na první pohled podobné Singletonu. Tady ale může vzniknout více objektů používajících stejné metody a atributy. Problém je, že statická metoda nemůže být virtuální. Tím se komplikují změny v kódu.

Jednostavový objekt (Monostate) class MojeTiskarna{ public: static void PridatTiskovouUlohu(); private: static std::queue<tiskovauloha> tiskovafronta; static PortTiskarny porttiskarny;... };

Stav (State) Pokud řešíme ve většině metod série obdobných podmínek, můžeme často na návrh aplikovat vzor stav (State). Stav slouží k rozdělení podmínek na stavy. Např.: if(student == "nový") {...} else {...} stav nový a stav starý

Stav (State) Tyto stavy jsou pak uloženy ve třídě jako její vnořené třídy. Každá metoda vnořené třídy implementuje jen jednu část podmínky = přehledné. Při přidání podmínek se jen vytvoří nové stavy = rozšiřitelné.

Klasická podmínka class Creature { bool isfrog; public: Creature() { isfrog = true; } void greet() { if(isfrog) cout << "Kvaaak!" << endl; else cout << "Nazdar!" << endl; } void kiss() { isfrog = false; } };

Stav (State)

Stav (State) class Creature { private: class State { public: virtual string response() = 0; }; class Frog : public State { public: string response() { return "Kvak!"; } };...

Praktický příklad http://objekty.vse.cz/objekty/vzory-state

Příkaz (Command) Příkaz (Command) je přepravka, ve které objektu předáte pokyn, co má udělat. Smysl: Můžete takto rozšiřovat funkčnost již existujících objektů. Stačí aby nové příkazy splňovaly definované rozhraní. Princip: příkaz zapouzdříme do objektu a předáme ho objektu na zpracování.

Příkaz (Command)

Příkaz (Command) class Prikaz{ public: virtual void proved()=0; }; class Privitani:public Prikaz{ void proved(){ cout << "Dobry vecer..." << endl; } };...

Příkaz (Command) class Vecernicek{ private: Prikaz* prikaz; public: void ulozprikaz(prikaz* novyprikaz){ prikaz = novyprikaz; } void provedprikaz(){ prikaz->proved(); } };

Příkaz (Command) Vecernicek* vecernik = new Vecernicek; Privitani* uvod = new Privitani; Rozlouceni* zaver = new Rozlouceni; vecernik->ulozprikaz(uvod); vecernik->provedprikaz(); vecernik->ulozprikaz(zaver); vecernik->provedprikaz();

Zástupce (Proxy) Zástupce (Proxy) slouží jako prostředník pro přístup k různým implementacím určitého rozhraní. Odstiňuje uživatele od objektu a sám řídí přístup. Zástupců může být řada typů Vzdálený zástupce: zastupuje objekt umístěný jinde (často i na jiném počítači). Virtualní zás.: odloží vytvoření objektu na dobu až je to potřeba, do té doby použije náhradu. Ochranný zás.: blokuje přístup k některým met. Chytrý odkaz: rozšiřuje funkcionalitu.

Zástupce (Proxy) class Rozhranni{ public: virtual void metoda1()=0; virtual void metoda2()=0; virtual void metoda3()=0; };

Zástupce (Proxy) class Implementace : public Rozhranni{ public: void metoda1(){ cout << "Implementace met1" << endl; } void metoda2(){ cout << "Implementace met2" << endl; }... };

Zástupce (Proxy) class Zastupce : public Rozhranni{ private: Rozhranni* impl; public: Zastupce(){impl = new Implementace; } ~Zastupce(){ delete(impl); } // rozhranni void metoda1(){ impl->metoda1(); } void metoda2(){ impl->metoda2(); } void metoda3(){ impl->metoda3(); } };

Adaptér Je velmi podobný vzoru Proxy. Účelem adaptéru je že vytvoří převodník pro metody z jiným rozhraním. Používá se v případě, že třída má jiné rozhraní, než bychom potřebovali, např. při přístupu k již hotovým knihovnám, atp. Existuje řada různých implementací adaptéru.

Adaptér

Řetěz (Chain) Celý název je Řetěz zodpovědnosti (Chain of responsibility). Podstata: Máme požadavek a snažíme se ho uspokojit. Existuje řada strategií (metod), které ho mohou uspokojit. Strategie zkoušíme za běhu postupně aplikovat, až nalezneme správnou nebo je všechny vyzkoušíme. Obvykle se pro vyřízení požadavku volá pouze jedna funkce, v tomto případě se o to pokouší postupně mnoho funkcí (expertní systémy).

Řetěz (Chain) http://objekty.vse.cz/objekty/vzory-chain

Další informace Rudolf Pecinovský: Návrhové vzory (Computer Press) Bruce Eckel: Myslíme v jazyce C++, díl 2 (Grada, Knihovna zkušeného prog.) Bruce Eckel: Thinking in C++, vol 2 (free, on-line) http://www.mindviewinc.com/books/ Bruce Eckel: Thinking in Patterns (free, on-line) A. Alexandrescu: Moderní programování v C++ (Computer Press)