Přechod „strukturovaných“ programátorů k OO programování

Slides:



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

Stručný úvod do UML.
VÝVOJ PROGRAMOVACÍCH JAZYKŮ PERSPEKTIVY ELEKTRONIKY 3. Celostátní seminář, 18. března 2003 Ing. Pavel Pokorný UNIVERZITA TOMÁŠE BATI VE ZLÍNĚ Fakulta technologická.
Vývoj aplikací s využitím JavaFX
Přednáška č. 3 Normalizace dat, Datová a funkční analýza
HYPERTEXT PREPROCESSOR. PROGRAMOVÁNÍ. DEFINICE POJMŮ Problém Problém nevyřešený, nežádoucí stav obvykle vyžaduje nějaké řešení Neřešitelný problém Neřešitelný.
Vaše jistota na trhu IT Quo vadis, programování? Rudolf PECINOVSKÝ 2012 – e-bezpečnost v Kraji Vysočina 1.
Databázové systémy Přednáška č. 2 Proces návrhu databáze.
Přednáška č. 5 Proces návrhu databáze
C# pro začátečníky Mgr. Jaromír Osčádal
Základy informatiky přednášky Kódování.
Programování v C++ Cvičení.
PROGRAMOVACÍ JAZYKY (c) Tralvex Yeap. All Rights Reserved.
Přínosy a druhy počítačových sítí. Jednou z nejvýznamnějších technologií používaných v oblasti výpočetních systémů jsou již řadu let počítačové sítě.
Z ČEHO SE POČÍTAČ SKLÁDÁ
J a v a Začínáme programovat Lucie Žoltá metody, objekty, konstruktor.
Tvorba webových aplikací
Definování prostředí pro provozování aplikace dosud jsme řešili projekt v obecné rovině aplikace bude ovšem provozována v konkrétním technickém a programovém.
Algoritmizace a programování
ÚČEL AUTOMATIZACE (c) Tralvex Yeap. All Rights Reserved.
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ředstavujeme službu Samepage
Seminář – Základy programování
Aukro.cz – projektový management v e-commerce Tereza Kabrdová.
Vyučovací hodina 1 vyučovací hodina: Opakování z minulé hodiny 5 min Nová látka 20 min Procvičení nové látky 15 min Shrnutí 5 min 2 vyučovací hodiny: Opakování.
13AMP 6. přednáška Ing. Martin Molhanec, CSc.. Co jsme se naučili naposled Synchronizace procesů Synchronizace procesů Producent-Konzument Producent-Konzument.
Algoritmizace a základy programování
Základy algoritmizace a programování
Programování Michal Žůrek.
Přehled současných způsobů tvorby programů
Modelovací jazyk UML. Jazyk UML je víceúčelový modelovací jazyk, který byl vyvinut speciálně pro účely softwarového inženýrství. Obsahuje formalizovaný.
Objektové programování
Strategy. Strategy – „All-in-1“ na začátek class AStrategy { public: virtual void Algorithm()=0; protected: AStrategy(); }; class SpecificStrategy: public.
Databázové systémy Přednáška č. 6 Proces návrhu databáze.
OBJEKTOVÉ METODOLOGIE – JEJICH UŽITÍ A VÝKLAD Ing. Martin Molhanec, CSc.
6. cvičení Polymorfismus
Možnosti modelování požadavků na informační systém
Dokumentace objektů a zveřejnění funkcí
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í
IB111 Programování a algoritmizace
Dokumentace informačního systému
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.
Systémy pro podporu managementu 2 Inteligentní systémy pro podporu rozhodování 1 (DSS a znalostní systémy)
Databázové modelování
Metodika objektového přístupu při tvorbě překladačů. Marek Běhálek Informatika a aplikovaná matematika FEI VŠB-TU Ostrava.
TISKOVÉ SESTAVY Michaela Žítková, 4. Y. Úkol: Vytvoření seznamu studentů pro hromadný výlet Úvod Program WinBase Postup při vytváření Závěr.
Databázové systémy Datové modely.
Vaše jistota na trhu IT Rozhraní a implementace Rudolf PECINOVSKÝ 2012 – Vývoj bezpečných aplikací 1.
Úvod do programování Vyučující: Mgr. Vítězslav Jersák
Informatika. Cíle výuky informatiky Studenti se mají seznámit se základními pojmy, problémy, postupy, výsledky a aplikacemi informatiky tak, aby je dokázali.
1 Prezentace Přírodopis lehce a zábavně – elektronická učebnice přírodopisu pro ZŠ
KURZ ALGORITMIZACE A PROGRAMOVÁNÍ V JAZYCE C Lekce č. 4: Programovací jazyk C Bc. Radek Libovický.
Testování aplikací v Javě Petr Adámek IBA CZ, s.r.o. © 2010.
SOFTWAROVÁ PODPORA PRO VYTVÁŘENÍ FUZZY MODELŮ Knihovna fuzzy procedur Ing. Petr Želasko, VŠB-TU Ostrava.
Vývojová prostředí Objektově Orientované Programování OB21-OP-EL-KON-DOL-M Orbis pictus 21. století.
NÁZEV ŠKOLY:SOŠ Net Office, spol. s r.o. Orlová Lutyně
Vypracoval / Roman Málek
Výukový materiál zpracován v rámci projektu
Návrhový vzor Flyweight
Operační systémy 9. Spolupráce mezi procesy
Tradiční metodiky vývoje softwaru
Příkazy cyklu (1) Umožňují vícekrát (nebo ani jednou) pro-vést určitý příkaz Jazyk C rozlišuje příkaz cyklu: s podmínkou na začátku: obecný tvar: while.
Soustava lineárních nerovnic
Název školy: Střední odborná škola stavební Karlovy Vary
Tradiční metody vývoje softwaru
Microsoft Excel Funkce Když. Microsoft Excel Funkce Když.
Monitor Object 1.
SIPVZ – úvodní modul P ICT a změny ve výuce (2 h) metodické poznámky.
GRASP Patterns.
Transkript prezentace:

Přechod „strukturovaných“ programátorů k OO programování Rudolf PECINOVSKÝ rudolf@pecinovsky.cz Common 2011

Obsah s odkazy Quo vadis, programování? Základní principy OOP Rozhraní Použití rozhraní při návrhu programu Problémy s přechodem na OOP Možné řešení: metodika výuky Design Patterns First Common 2011

Quo vadis, programování? Common 2011

Programování se vyvíjí (1/3) Dříve Řada běžných, často se vyskytujících úloh stále čekala na vyřešení Programy pracovaly samostatně, navzájem příliš nespolupracovaly Klíčovou úlohou programátora byl návrh algoritmů a základních datových struktur Nyní Většina běžných úloh je vyřešena a řešení jsou dostupná v komponentách či knihovnách Nové program jsou téměř vždy součástí rozsáhlejších aplikací a rámců Důležitější než znalost algoritmů je znalost knihoven a aplikačních rámců, v nichž jsou potřebné algoritmy a datové struktury připraveny Klíčovou úlohou je návrh architektury systému Common 2011

Programování se vyvíjí (2/3) Dříve Metodika vývoje programů počítala s pevným zadáním Zákazníci hledali firmu, která jejich projekt naprogramuje O výsledné podobě projektu rozhodovali analytici a programátoři Při vývoji programů se kladla váha především na jejich efektivitu U programátorů byla oceňována jejich schopnost vyvíjet programy, s malými HW požadavky Nyní Zadání většiny vyvíjených projektů se v průběhu vývoje neustále mění Programátorské firmy hledají zákazníky, kteří si u nich objednají tvorbu projektu O výsledné podobě projektu rozhoduje zákazník Při vývoji programů se klade váha především na jejich spravovatelnost a modifikovatelnost U programátorů je oceňována jejich schopnost vyvíjet programy, které je možno rychle a levně přizpůsobovat neustále se měnícím požadavkům zákazníka Common 2011

Programování se vyvíjí (3/3) Dříve Prvotní úlohou programátora bylo vymyslet, jak úkol vyřešit Testy se většinou navrhovaly po dokončení projektu či jeho části a spouštěly se na závěr před odevzdáním projektu (byl-li čas) Testy navrhovali programátoři a ověřovali v nich, že program dělá to, co chtěl programátor naprogramovat Návrh testů byl interní záležitostí vývojového týmu Nyní Prvotní úlohou programátora je zjistit, jestli už někde není problém vyřešen Stále častěji se testy navrhují před začátkem vývoje každé části a spouští se v průběhu celého vývoje po každé drobné změně Testy se navrhují ve spolupráci se zákazníkem a ověřuje se v nich, že program dělá to, do po něm zákazník požadoval Návrh testů se často stává součástí smlouvy o vývoji programu Common 2011

Shrnutí Doba programován jako umění skončila, nastupuje programování jako technologie Zákazník má jediné kritérium: TOC Proto dává přednost programům méně dokonalým, ale snadno spravovatelným a modifikovatelným Doba, kdy je cena poměrně výkonného počítače srovnatelná s týdenními náklady na programátora, dále upřednostňuje rychlost dodání před rychlostí budoucího zpracování dat Časté změny v týmu spolu s častými modifikacemi vyžadují psát programy maximálně srozumitelné, tj. tak, aby jejich vývoj mohl být kdykoliv předán některému z kolegů Common 2011

Priority současného programování Funkčnost Robustnost Modifikovatelnost Srozumitelnost Vstřícnost ke změnám Spravovatelnost Znovupoužitelnost Efektivita Program nemusí být rychlý, stačí, když jej zákazník považuje za dostatečně rychlý Napsat program, kterému rozumí počítač, umí každý trouba. Dobří programátoři píší programy, kterým rozumí lidé. Marin Fowler, Refactoring Common 2011

Základní principy OOP Common 2011

Všechno je objekt První myšlenky se objevily v jazyku Simula, což je jazyk vyvinutý pro programování simulací Později chytrým došlo: Každý program je simulací reálného či virtuálního světa Ve světě lze vše považovat za objekt => má-li být simulace přesná, musí umět s objekty pracovat Myšlenku, že vše je objekt, OOP rozšiřuje na vše, co můžeme označit podstatným jménem … => jako objekt jsou v OO programech zpracovávány i vlastnosti (velikost, barva, směr, krása …) děje (spojení, komunikace, výpočet, …) události (spuštění, přerušení, ukončení, …) … Common 2011

Objekty a zprávy Každý objekt má nějaké vlastnosti a schopnosti Vlastnosti popisují okamžitý stav objektu, jejich hodnoty se ukládají do konstant / proměnných objektu Schopnosti objekt demonstruje tím, že je schopen odpovědět na odpovídající zprávu V reálném světě jsou všechny děje důsledkem toho, že spolu objekty navzájem interagují – jeden objekt působí na druhý a ten na to reaguje Interakce objektů se v OO programech simuluje zasíláním zpráv Židle zašle podlaze zprávu o své váze, podlaha ji odpoví, jestli ji unese Část kódu definující reakci objektu na zaslanou zprávu nazýváme metoda Common 2011

Objekty a třídy Některé jazyky (C++, C#, Java) sdružují objekty do tříd a označují pak jednotlivé objekty dané skupiny jako instance příslušné třídy Třídu můžeme označit podstatným jménem => podle předchozí zásady je tedy třída objekt Třída je zvláštní druh objektu, který umí na požádání vytvořit svoji instanci (třída je „forma“ na vytváření svých instancí) Třídy jsou jediné objekty, jež umějí vytvářet jiné objekty Objekt třídy není ve většině jazyků instancí žádné třídy tříd Java a další moderní jazyky umějí pracovat se „zástupcem objektu třídy“ Vzájemné závislosti tříd, resp. objektů daného programu znázorňujeme v diagramu tříd, resp. v diagramu objektů Oba diagramy jsou součástí sady diagramů označované jako grafický jazyk UML (Unified Modeling Language) V UML vypadají oba výše zmíněné diagramy velmi podobně Common 2011

Diagram tříd jednoduchého projektu Při pohledu na UML klasicky orientovaného programátora hned napadne: „Ten obrázek můj problém nevyřeší“ Obrázek však umožní vyjadřovat se v pojmech, kterým bude rozumět i zadavatel / zákazník Diagram tříd znázorňuje architekturu systému Umožní rozdělit problém na jednotlivé části a výrazně tak urychlit vývoj Umožní udržovat povědomí o vzájemných souvislostech Common 2011

Strukturovaný × OO program Strukturovaný program „=“ posloupnost příkazů Analýza: vymýšlejí se postupy Stavební kameny: procedury/funkce; (proměnné) Výsledek: většinou samostatný program Vedlejší cíle: efektivita Objektově orientovaný program = množina objektů, které si posílají zprávy Analýza: definují se účastníci a jejich spolupráce Stavební kameny: třídy a objekty Výsledek: velmi často komponenta, služba či jiná část celku Vedlejší cíle: přehlednost, modifikovatelnost, znovupoužitelnost OOP vede k výrazně jinému způsob uvažování než klasické strukturované programování Kurzy, které neučí tento nový způsob uvažování neučí OO programování ale pouze kódování v OO jazyce Common 2011

Základní pilíře OOP Zapouzdření (kód je pohromadě se zpracovávanými daty) Skrývání implementace (nikdo nemá mít šanci zjistit, jak je program implementován) Zvýšení bezpečnosti a robustnosti (nemožnost nekorektního použití) Usnadnění budoucích modifikací Identita Každá zpráva musí mít svého adresáta, nelze ji posla „do prostoru“ Objekt sám rozhodne, jak na zprávu zareaguje Důsledek: polymorfizmus – operativní změna typu za chodu programu (nyní jsem číšník, za chvíli budu obsluhovaný host) Skládání Objekt může obsahovat jiné objekty Dědičnost – speciální případ, při němž s objektem převezmu i jeho rozhraní Omezuje duplicity v kódu Nebezpečí špatného použití (narušuje zapouzdření) Dědičnost používáme, až jen když jsou ostatní řešení nešikovná Používání návrhových vzorů Proč bych měl vymýšlet něco, co už je vymyšlené, a je to vymyšlené dobře Common 2011

Návrhové vzory – Design Patterns Programátorský ekvivalent matematických vzorečků Do návrhových vzorů se nedosazují čísla, ale objekty a třídy Výhody: Zrychlují návrh (řešení se nevymýšlí, ale jenom použije) Zkvalitňují návrh – jsou ověřené, takže výrazně snižují pravděpodobnost potenciálních chyb typu na něco jsme zapomněli Zjednodušují a zpřesňují komunikaci mezi členy týmu (větou, že diskriminant je záporný, řeknu znalým jednoduše řadu věcí, které bych musel jinak složitě vysvětlovat) Znalost návrhových vzorů patří k povinné výbavě současného objektově orientovaného programátora, a proto by se měly učit co nejdříve Common 2011

Rozhraní Common 2011

Trocha mytologie Janus římský bůh vchodů, dveří, počátku a konce Měl dvě tváře: jedna hleděla do budoucnosti, druhá do minulosti I program má dvě tváře: Rozhraní × Implementace Common 2011

Rozhraní Implementace Definuje, co bude zbytek programu o dané entitě vědět Všem na sebe všechno řekne Zabezpečuje, aby entita plnila svoji funkci Všechno se snaží maximálně utajit I samotné rozhraní má dvě složky Signatura Specifikuje vlastnosti, které může zkontrolovat překladač (názvy, typy, …) Kontrakt Doplňuje další důležité informace, které však překladač zkontrolovat nedokáže – o jejich dodržení se musí postarat programátor Common 2011

Rozhraní a implementace metody Rozhraní – signatura Jmenuje se blikni Nemá žádné parametry Nic nevrací Rozhraní – kontrakt Světlo nejprve „rozsvítí“ Nechá je „svítit“ půl vteřiny Po půl vteřině je opět „zhasne“ Implementace K rozsvícení světla používá svoji metodu rozsviť() Půlvteřinové svícení zabezpečí pozastavením programu pomocí metody čekej() třídy IO, které předá počet milisekund čekání Zhasnutí realizuje zavoláním své metody zhasni() public void blikni() { rozsviť(); IO.čekej( 500 ); zhasni(); } Common 2011

interface – formalizovaný zápis rozhraní Programujte proti rozhraní, ne proti implementaci (Program to an interface, not an implementation) Java zavedla speciální konstrukci umožňující deklarovat rozhraní bez jakékoliv zmínky o implementaci Konstrukce dostala název interface – je to vlastně třída bez implementace Signatura rozhraní je dána deklaracemi metod a statických konstant (konstanty se nedoporučuje používat) Kontrakt je (stejně jako u standardních tříd) definován prostřednictvím dokumentačních komentářů interface nemá implementaci => nemůže mít instance Za jeho instance se vydávají instance tříd, které se veřejně přihlásí k implementaci daného rozhraní S nadsázkou můžeme říci, že celé moderní programování je o tom, jak co nejlépe využít možností rozhraní Common 2011

Složitější projekt Common 2011

Použití rozhraní při návrhu programu Common 2011

Oddělit části kódu, jež se mohou měnit Jakmile používám nějakou část programu, tak na ní závisím (přizpůsobovat se musí vždy volající, ne volaný) Každá změna kódu může ovlivnit části, které na upravené části závisí; jejich úprava může ovlivnit další části atd. Každá změna kódu hrozí dominovým efektem Dominový efekt mohu zastavit oddělením měněné části od okolního kódu Jedním z nejlepších postupů je vložit mezi obě části rozhraní Příklad: Kalkulačka Common 2011

Klasicky navržená kalkulačka Klasický přístup Odděluje se návrh CPU and GUI; – Třídu GUI navrhuje vyučující – Třídu CPU navrhují studenti Stisk tlačítka z každé skupiny volá partnerskou metodu v CPU Třídy jsou těsně provázané což má své nepříjemné důsledky: S každou změnou definice CPU je třeba změnit definic GUI a naopak Každá verze studentského zadání vyžaduje vlastní verzi definice GUI Chceme-li po studentech, aby u zkoušky svoji třídu upravili, musíme příslušně upravit i námi definované GUI Common 2011

Po aplikaci vzoru Most Třída CPU implementuje rozhraní ICPU deklarující tři metody: RozměrKláves getRozměr() List<String> getPopisky() String stisknuto( String label ) Konstruktor třídy GUI Dostane instanci of CPU jako parametr Zeptá se jí na požadovaný rozměr klávesnice a seznam požadovaných popisků na tlačítcích Připraví GUI podle obdržených požadavků Běh programu: Instance GUI zjistí, jaké tlačítko bylo stisknuto a zašle instanci CPU zprávu s jeho popiskem Instance CPU zjistí, co stisk znamená, a vrátí GUI nový obsah displeje Common 2011

Co jsme tím získali GUI může spolupracovat s různými CPU; stačí, aby spolupracující CPU implementovala rozhraní ICPU Přiblížíme studentům význam a použití rozhraní Ukážeme, že tvůrce GUI nemusí znát spolupracující CPU předem, instance GUI se ji může dozvědět až při svém zrodu Můžeme do CPU svobodně přidávat další a další funkce, aniž bychom museli jakkoliv upravovat třídu GUI Můžeme připravit automatické testy Common 2011

Testování sady programů Testovací třída se bude tvářit, že je zvláštní GUI Třída Verze dodá požadovanou sadu popisků spolu s testy definujícími požadované reakce na stisk kláves Rozhraní ICPU rozšíříme o metodu vracející pořadí řešeného zadání int getZadání() Můžeme přidat značkovací rozhraní IGUI, jež budou implementovat třídy, které se chtěji vydávat za GUI Common 2011

Problémy s přechodem na OOP Shrnutí či téma Common 2011

Nevýhody klasicky orientovaných kurzů Řada kurzů zmíní na počátku letmo základní zásady OOP, avšak následně se soustředí především na syntaxi jazyka a demonstraci probíraných konstrukcí prostřednictvím jednoduchých AHA programů AHA příklad je superjednoduchý demonstrační příklad, po jehož analýze si student řekne: „Aha, takto to funguje“ Mezi demonstrací principu na jednoduchém AHA příkladu typu Hello World a použitím vysvětlovaného principu v reálné situaci bývá často dlouhá a strastiplná poznávací cesta I když kurzy tvrdí, že učí OOP, učí ve skutečnosti většinou jen procedurální programování v OO jazyce, takže namísto OO paradigmatu učí jenom kódování v OO jazyce Common 2011

Nevýhody předčasné koncentrace na kód Takovýto „bottom-up“ přístup vychovává návyky, které následně ztěžují komunikaci se zákazníky Takto vychovaný programátor začne hned po obdržení zadání přemýšlet, jak by program zakódoval a hovoří v termínech svého kódu Mezi ním a zákazníkem vznikne sémantická mezera Common 2011

Postup vývoje OO programu Aplikací zásad OOP můžeme sémantickou mezeru výrazně zmenšit Definují se základní požadované funkce programu specifikují se případy užití (use cases) Definují se účastníci, tj. objekty, které vystupují při realizaci požadované funkčnosti V řadě případů se definují rovnou třídy oněch účastníků Definují se vlastnosti a schopnosti jednotlivých účastníků Jakých stavů mohou nabývat Jakým zprávám budou rozumět a umět na ně reagovat Až sem bývá zákazník schopen komunikovat a případně modifikovat špatně pochopné zadání či návrh realizace Definuje se způsob (algoritmus), jak bude vše realizováno Tady už se zákazník většinou ztratí Common 2011

1. Případy užití Common 2011

2. Účastníci Common 2011

3. Vlastnosti a schopnosti Common 2011

Děti jsou na tom lépe Děti před pubertou jsou schopny přijmout nová fakta, aniž by si je musely spojovat s tím, co již znají; s postupným získáváním dalších informací si předchozí informace propojují a zařazují do kontextu Puberta mění naše myšlení z konkrétního na abstraktní a při té příležitosti nás o tuto schopnost připraví Člověk po pubertě si každý nový poznatek okamžitě podvědomě propojí s tím, co zná Programátor poslouchající výklad o OOP podvědomě převádí vysvětlované termíny do paradigmatu, v němž je doma; při tomto převodu dochází k výrazné desinterpretaci pojmů Common 2011

Možné řešení: metodika výuky Design Patterns First Common 2011

Interaktivní režim Začíná v interaktivním režimu prací s objekty a třídami Využívá možnosti používaného prostředí definovat i v interaktivním režimu vlastní třídu Již v interaktivním režimu seznamuje s konstrukcí interface včetně dědičnosti rozhraní a učí její význam v programech Již v interaktivním režimu seznamuje s návrhovými vzory Použitými v používané aplikaci Knihovní třída, Jedináček, Výčtový typ Umožňujícími řešení řešených problémů Služebník, Prostředník, Pozorovatel, Poté se přejde do klasického textového režimu, v němž se znovu projde látka probraná před tím v interaktivním režimu Common 2011

Ranní ptáče Respektuje pedagogické pravidlo ranního ptáčete (early bird), tj. začíná se výukou nejdůležitějších principů Od počátku studenti pracují na relativně složitých projektech, u nichž přidávají či zdokonalují nějakou jejich funkci anebo je používají jako knihovnu Studenti si přitom osvojí postup, při němž každou úlohu řeší nejprve na vyšší úrovni abstrakce, a teprve pak přejdou ke kódu Od samého počátku se seznamují s nejdůležitějšími principy včetně konstrukce interface a návrhových vzorů Poté zvládnutí interaktivního režimu začneme s psaním kódu, při němž se veškerý předchozí výklad ještě jednou zopakuje Common 2011

Tvorba kódu Jakmile začnou studenti tvořit vlastní kód, velmi záhy se začnou učit, kdy, proč a jak navrhnout vlastní interface Před výkladem algoritmických konstrukcí učí objektové techniky nahrazující tyto konstrukce Návrhový vzor Stav Algoritmické konstrukce jsou probírány až po objektových Před výkladem dědičnosti je probrán a procvičen návrhový vzor Dekorátor Dědičnost tříd je zavedena jako automatizovaná aplikace návrhového vzoru Dekorátor Common 2011

Rudolf Pecinovský mail: rudolf@pecinovsky.cz ICQ: 158 156 600 Děkuji za pozornost Rudolf Pecinovský mail: rudolf@pecinovsky.cz ICQ: 158 156 600 Common 2011

Common 2011

Pgm Používaná písma a objekty Pgm Příliš žluťoučký kůň úpěl ďábelské ódy (Demi) Pgm Příliš žluťoučký kůň úpěl ďábelské ódy (Medium) Pgm Příliš žluťoučký kůň úpěl ďábelské ódy (Cond) Příliš žluťoučký kůň úpěl ďábelské ódy (Heavy) Příliš žluťoučký kůň úpěl ďábelské ódy (Franklin Gothic Book) Příliš žluťoučký kůň úpěl ďábelské ódy (Comic Sans MS) Příliš žluťoučký kůň úpěl ďábelské ódy (Consolas) Příliš žluťoučký kůň úpěl ďábelské ódy Příliš žluťoučký kůň úpěl ďábelské ódy Opakování Program Keyword Příliš žluťoučký kůň úpěl ďábelské ódy Common 2011