Programovací techniky

Naučit se programovat sám? Jde to! | ČtiDoma.cz

Kategorie : Programování

Podkategorie : Programování

Kapitol: 20(0)

POPIS:

Jaké jsou programovací techniky.

Programovací techniky

Softwarový projekt

Typy SW projektů (dle zadavatele)

• Zakázkový software

–Zadavatel má nápad a peníze, ale neumí to udělat    najde si realizátora

–Např. ŠIS

–Podtyp: subdodávka komplexního řešení

• Hlavní dodavatel je vůči subdodovatelůmv roli zadavatele

• Software pro volný trh

–Firma vymyslí a vytvoří program, pak se ho snaží prodat (mnoha) zákazníkům

–Např. MS Windows, Adobe Photoshop, …

• Interní projekt

–Firma si pro své vnitřní potřeby vytvoří software (zadavatel a realizátor jsou různá oddělení stejné firmy)

• Jiné typy projektů

–Open source projekty (Linux, Firefox, …)

• Řada projektů je zvláštních: není zde jasný zadavatel (co má program dělat), část práce odvedou dobrovolníci

(zdarma) –často role zadavatele, realizátora i finančního zdroje hraje komunita

My se dále podrobněji podíváme na tvorbu zakázkového software (dobře se na tom ukazují jednotlivé činnosti)

• Tedy jaké činnosti zahrnuje tvorba software?

–(U zakázkového typu)

Zadavatel     realizátor

• Zadavatel musí sdělit, co vlastně chce

• Přenos myšlenky není nikdy dokonalý

–Nevyřčené předpoklady (na obou stranách)

–Špatné pochopení (na obou stranách)

–Neznalosti (na obou stranách)

–Střet dvou světů

• Člověk (vágní) a počítač (přesný)

–Co s tím?

Zadavatel ↔realizátor

• Komunikace musí být obousměrná (↔)

–Aktivně se ptát

• Proč to chcete? Co je cílem?

–Někdy je lepší úplně jiné řešení, než s kterým zadavatel původně přijde

–Vyjasňovat si, ověřovat si

• Nakreslit, ukázat (ukázkové verze co nejdříve –nemusí být plně funkční)

• Např. use cases(případy užití) –jak se program bude používat (scénáře užívání)

• Zápis dohodnutého   formální specifikace

Use case

• Seznam kroků, jak v programu dosáhnout nějakého cíle

–Obvykle kroky popisující interakci mezi uživatelem a programem

• Např. přihlášení na zkoušku v ŠISu:

1. Student vybere akci „přihlášení na zkoušku“.

2. ŠIS vypíše seznam předmětů, které má student v daný semestr zapsané

3. Student vybere, o který předmět mu jde

4. ŠIS vypíše seznam zkouškových a zápočtových termínů daného předmětu (na které se v aktuální okamžik dá přihlásit, tj. jsme v časovém intervalu začátek přihlášení –konec přihlášení)

5. Student si vybere termín a kliknutím na „Přihlásit se“ se na něj přihlásí

6. ŠIS zobrazí potvrzení, že se přihlášení povedlo, a zobrazí seznam všech termínů, na které je student aktuálně přihlášen

Use case: zápis a přínosy

• Zápis use cases:

–Různě (text i diagramy), často se využívá jazyk UML

• Oproti prostému seznamu funkcí programu mají use casesnapříklad tyto přínosy:

–Umožňují programátorům lépe pochopit, jak se dané funkce budou využívat (např. jaký je jejich kontext, jaké je pořadí), a tak vedou k lepšímu návrhu programu (návrh uživatelského rozhraní, volba vhodných datových struktur a algoritmů)

–Obvykle zachycují to nejdůležitější, co má program umět (tj. lépe se stanovují priority)

–Vedou k upřesňování ošidných situací („co má program dělat, když se stane to a to“) –a to už v rané části vývoje (specifikace, návrh, ne až v okamžiku implementace)

Formální specifikace

• Specifikace:


 

–Funkce programu

•Programátorské rozhraní (API), protokoly, …

–Uživatelské rozhraní programu

–Vlastnosti (rychlost)

–Platforma (HW i SW)

Změna je život

• Připravit se na změny programu

–Proč?

• Změna názoru, nový nápad, změnila se situace (na trhu, legislativa, v podniku, …)

–Počítat s tím v časovém plánu

–Návrh programu udělat (trochu) obecnější

• Aby změny byly snazší

Mám specifikaci, už píšu kód?

• Kdepak, nejdříve musím vybrat…

–Vhodné nástroje, prostředky a lidi

• Platformu (není-li součástí zadání)

• Knihovny(frameworky, toolkity, grafický engine)

–Nemá smysl vše tvořit od nuly, je možné využít už hotová řešení

• Programovací jazyk

• Vývojové prostředí (IDE)

• Lidé (role a počet)

• Metoda vývoje / řízení projektu

Mám specifikaci, už píšu kód?

• Kdepak, nejdříve musím udělat analýzu (rozbor) a poté udělat…

–Návrh (design)

• Celková architektura (moduly, objekty, co bude na serveru, co na klientovi, rozhraní, protokoly …)

• Algoritmy

• Datové struktury

• Uživatelské rozhraní

Mám specifikaci, už píšu kód?

• Kdepak, nejdříve si celý projekt musím naplánovat…

–Čas (termíny)

–Finance

–Organizační (postup, priority)

–Právnízáležitosti (smlouvy, licence)

Testování

• Každý program obsahuje chyby    testování, ověřování, kontrola kvality

–Funkční chyby

–Nemá požadované vlastnosti („je to ošklivé a pomalé“)

–Bezpečnostní chyby

Management

• Funkce manažera*

–Plánování–stanovení cílů, určení variant, určení termínů

–Organizování–stanovení úkolů jednotlivým lidem a určování pravomocí, odpovědnost, organizační struktura

–Vedení–ovlivňování a motivování lidí, usměrňování a odměňování

–Rozhodování–také řízení rizik

–Kontrola–zjišťování odchylek, hledání příčin a způsobů nápravy

• Tím jsme shrnuli předchozích 5 snímků

Program už mi funguje, je hotovo?

• Ani náhodou:

–Dokumentace

• Uživatelská –aby uživatelé věděli, jak produkt nainstalovat a používat

• Programátorská –aby programátor věděl, kam „šáhnout“, když chce něco změnit, opravit nebo vylepšit

• Popř. projektová dokumentace (finance, čas, …) –aby podobné projekty proběhly stejně dobře nebo lépe

–Prodej, distribuce, propagace (u software pro volný trh)

–Nasazení software u zákazníka (deployment), integrace do jeho prostředí

–Podpora

Dokumentace

• Uživatelská

–Aby uživatelé věděli, jak produkt a používat

–Popis instalace(systémové požadavky: HW a SW), představení funkcí programu, vysvětlení ovládání, …

• Programátorská

–Aby programátor věděl, kam „šáhnout“, když chce něco změnit, opravit nebo vylepšit


 

–Popis struktury programu, složitějších algoritmů, datových struktur, rozhraní, protokolů

• Zahrnuje i komentáře ve zdrojovém kódu

• Projektová

–Aby byl projekt dokončen a aby podobné projekty proběhly stejně dobře nebo lépe

–Co se kdy dohodlo (a popř. i důvody), jak dlouho daná věc trvala, kolik to stálo peněz,

Podpora (SLA)

• SLA(Service-LevelAgreement)

–Dohoda o úrovni poskytovaných služeb

• Hotline, Help desk, Call centrum

–Osobně/telefonicky/e-mail/webový formulář?

–Jen čtvrtek 10:00–16:00, nebo non-stop každý den?

• Školení uživatelů a správců systému

• Oprava chyb

–Jak rychlá reakce na nahlášenou chybu?

• Další rozvoj programu (nové funkce)

–Dohoda o tom:

• jaké služby, jaká úroveň, jak dlouho (30 dní, 1 rok, 5 let, …), za jakou cenu

Fáze tvorby programu(technický pohled)

1.  Zadání (co má dělat)

2.  Algoritmus(postup, jak to má dělat)

3.  Zdrojový kód(text)

4.  Strojový kód(01001001…)

Algoritmus

• Postup řešení dané úlohy

• Například algoritmus sečtení dvou dlouhých celých čísel (487512493 + 9345678):

–Napiš čísla pod sebe (zarovnáno vpravo)

–Postupuj po číslicích zprava doleva:

• Sečti dvě číslice nad sebou

• Je-li výsledek 0 až 9, zapiš výsledek

• Je-li výsledek 10 a více, zapiš poslední číslici a 1 jde dále (do následujícího součtu)

• Pokud číslice chybí (číslo je krátké), domysli si tam 0

Zdrojový kód (source code)

• Text, který:

–Napsán člověkem(většinou)

–Je v programovacím jazyce

–Popisuje chování programu

• Příslušný textový soubor má příponu obvykle podle použitého programovacího jazyka

–*.cpp(C++), *.cs(C#), *.java(Java), *.pas (Pascal), *.php(PHP), *.js(JavaScript), …

Strojový kód (machinecode)

• Binární kód

–Generován (většinou)

–V jazyce stroje (počítače, hardware, procesoru)

• Rozumí mu procesor (CPU)

• Pro různé procesory může být strojový kód jiný

–Posloupnost příkazů (instrukcí) pro počítač

• Binární soubory se strojovým kódem mívají příponu podle zvyklostí daného OS:

–Windows: *.com, *.exe, *.dll

•exe= executable(spustitelný, proveditelný), jde o formát PE (Portable Executable)

–Linux: bez přípony (ale s právem „execute“)

• Jde o formát ELF (Executableand LinkableFormat)

• Zdrojový kód není na počítači (hardware) přímo spustitelný (proveditelný)

–Hardware (procesor) mu nerozumí

• Jak vykonat takový program?

–Interpretace

• Interpret provede ty kroky, které jsou ve zdrojovém kódu uvedeny

–Překlad(kompilace) do strojového kódu

• Překladač (compiler) převede (přeloží) program do podoby strojového kódu dané platformy (procesoru)

Interpretace (interpretation)

• Speciální program, tzv. interpret, vezme jako svůj vstup daný zdrojový kód (text) a provede příslušné akce (které jsou ve zdrojovém kódu uvedeny)

–Daný programovací jazyk se pak často označuje jako skriptovací jazyk(scriptinglanguage)

• PHP, Javascript, Python, batchfile(*.bat), shellscript(*.sh), …


 

–Interpret je ve formě strojového kódu (např. *.exe)

–Příklady interpretrů:

• JavaScriptengine(součást webových prohlížečů), cmd.exe (pro dávkové soubory *.batna Windows), Bash(pro tzv. shellskripty *.shna Linuxu), php.exe (PHP engine), …

Překlad (compilation)

• Převod z programovacího jazyka (tj. zdrojového kódu) do jazyka stroje (strojového kódu)

–Provádí speciální program: překladač(compiler)

• Musí umět oba jazyky

• Je ve formě strojového kódu (např. *.exe)

• Příklady:

–cl.exe (Microsoft VisualStudio), GCC (GNU CompilerCollection), Intel C++ Compiler(překladač od výrobce procesorů)

–Typické pro tyto jazyky:

• Pascal, C, C++

Překlad do bajtkódu(bytecode)

• Překlad nemusí být vždy až do strojového kódu nějakého procesoru (hardware)

• Překlad může být jen „na půl cesty“, do kódu nějakého pomyslného (virtuálního) procesoru

–Typické pro jazyky Java nebo C#

–Takový kód se označuje jako bajtkód(bytecode) nebo p-code(portable, přenositelný)

• Pro člověka je obvykle nečitelný (jde o binární kód)

• U C# se bajtkódukládá do souborů *.exe, u jazyka Java je to *.class

–Pro běh bajtkóduje nutný speciální program, který chod takového virtuálního procesoru (stroje) simuluje

• Např. Java Runtime Environment(JRE, běhové prostředí Java) nebo CommonLanguageRuntime (CLR, pro C#/.NET)

Překlad do bajtkódu(poznámky)

• Obsah *.exesouboru může být dvojí:

–Strojový kód (přímo spustitelný na procesoru)

–Bajtkód(pro spuštění je třeba CLR, což v praxi znamená mít nainstalován .NET Framework)

• U jazyka Java můžete narazit na dva typy souborů:

–*.java(zdrojový kód = čitelný text)

–*.class(bajtkód, nečitelný, pro spuštění je třeba JRE)

• Popř. ještě *.jar (což je ZIP archiv, kde je „zabaleno“ několik *.classa jiných souborů)

AOT vs. JIT kompilace

• K překladu programu může dojít ve dvou okamžicích:

–Před spuštěním programu (AOT = ahead-of-timecompilation)

• Výsledek překladu je třeba uložit do nějakého souboru (např. *.exe, *.class)

–V okamžiku spuštění/běhu programu (JIT = just-in-timecompilation)

• Výsledek překladu stačí mít v operační paměti (RAM), není nutné nic ukládat do souboru

• Umožňuje různé optimalizace kódu (např. využití možností procesoru, na kterém program právě běží, nebo využití znalosti, která část kódu se jak často využívá) pro zlepšení „kvality“ překladu a tím zvýšení výkonu programu

• Prodlužuje čas potřebný pro spuštění programu

Rozdíly mezi metodami

• Přenositelnost programů

–Strojový kód je nepřenositelný

• Na jiné platformě fungovat nemusí, ať už z důvodu odlišného formátu souboru (PE/ELF), tak z důvodu odlišných možností hardware (procesoru)

–Zdrojový kód a bajtkódjsou přenositelné

• Ale pro svůj běh vyžadují speciální program (interpret nebo virtuální stroj / běhové prostředí)

• Rychlost běhu programu

–Strojový kód je (může být) nejrychlejší

• Může využít všech možností daného hardware (procesoru)

–Bajtkódve virtuálním stroji je pomalejší

• Je zde režie běhu samotného virtuálního stroje

• Kód pro virtuální stroj nemůže využít všech výhod aktuální platformy (virtuální stroj musí být schopen běžet na více platformách, takže může nabízet jen ty vlastnosti, které jsou pro všechny podporované platformy společné)

–Interpretace je (obvykle) nejpomalejší

• Zdrojový kód má strukturu vzdálenější stroji (než bajtkód)

Použití metod

• Pro řadu programovacích jazyků lze použít (se používá) více uvedených metod

–Java: bytecodea dále běh na virtuálním stroji nebo JIT kompilace

–JavaScript: tradičně interpretovaný, ale v nových verzích webových prohlížečů probíhá JIT kompilace

–PHP: tradičně interpretovaný, ale existují i překladače do bytecode(a dále virtuální stroj nebo JIT kompilace)

–Python: bytecodea virtuální stroj (CPython); JIT kompilace (PyPy)

Použití metod: Android

• Android verze 1.0–2.1


 

–Programátor napsal zdrojový kód v jazyce Java (*.java)

–Ten se běžným překladačem přeložil na bajtkódpro JVM (*.class)

–Ten se programem „dx“ přeložil na bajtkódpro virtuální stroj Dalvik(*.dex= DalvikExecutable)

• Dalvika JVM se liší instrukční sadou, typem stroje (stack/register) atd., Dalvikje optimalizovaný pro mobilní zařízení (potřebuje málo paměti apod.)

• Android verze 2.2–4.4

–Dalvikprovádí JIT kompilaci, aby programy běžely rychleji

• Android verze 5.0 („Lollipop“)

–Dalvikje nahrazen ARTem(ART = Android Runtime)

• ART provádí AOT kompilaci (v okamžiku instalace aplikace), což dále zvyšuje výkon; používá se souborový formát

ELF (jako v Linuxu)

Syntax, nástroje, platforma

Syntax = pravidla zápisu

• Sémantika = význam zápisu

Příklad syntaxe: e-mailová adresa

• RFC 5322 (Internet MessageFormat)

–Addressspecification

• http://tools.ietf.org/html/rfc5322#section-3.4

E-mailová adresa (pravidla)

•E-mailová adresa má 3 části:

–Lokální část (např. název schránky)

• Může obsahovat jen některé znaky

–Určitě lze a–z, 0–9, tečku

–Určitě lze některé další znaky (pomlčku, …) a určitě nelze některé „divné“ znaky (např. s diakritikou)

»To je třeba nastudovat z norem (RFC)

–Určitě nelze mezeru (jinak nepoznám konec adresy)

–Určitě nelze „@“ (jinak nepoznám konec lokální části)

–Znak „@“

–Doménové jméno (serveru)

• Platí obecná pravidla pro zápis doménových jmen

–Viz příslušné normy (RFC)

E-mailová adresa (syntax)

• Popis syntaxe na předchozím snímku je špatně

–Lokální část může obsahovat mezeru i zavináč

–Tečka v lokální části může být jen „uvnitř“ (ne na krajích)

–Je možné použít skoro libovolný znak z Unicode*

• Platné e-mailové adresy: hodne.dlouha.lokalni.cast@dlouha.domena.example.com "martintrcka"@example.com

" "@example.org "martin@vsmiep.cz"@example.com

!#$%&'*+-/=?^_`{}|~@example.org "()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a"@example.org üñîçøðé@üñîçøðé.com

* Dle Wikipedie (v RFC 5322 jsem to nenašel, asi to bude v jiné normě). Všechny výše uvedené příklady jsou převzaty (a případně mírně upraveny) z článku http://en.wikipedia.org/w/index.php?title=Email_address&oldid=597633294#Examples5. 3. Kompletní zápis adresy

• Může obsahovat i jméno:

martin.trcka@vsmie.cz

<martin.trcka@vsmie.cz> Trcka<martin.trcka@vsmie.cz>

"Martin Trcka" <martin.trcka@vsmie.cz> "Dwayne\"TheRock\" Johnson" <r@rock.cz>

• Dále může:

–Obsahovat komentář (v kulatých závorkách), být rozdělen na více řádků nebo obsahovat tzv. bílé znaky (whitespace)

• http://tools.ietf.org/html/rfc5322#section-3.2.2

• http://cs.wikipedia.org/wiki/Bílý_znak

–Být zapsán podle zastaralých (obsolete), volnějších pravidel

• http://tools.ietf.org/html/rfc5322#section-4

Syntax vs. sémantika

• Syntakticky správné e-mailové adresy, ale sémanticky špatné:

–x@vsmie.cz

• Schránka s tímto jménem neexistuje


 

–martin.trcka@x.vsmie.cz

–martin.trcka@vsmiex.cz

–martin.trcka@vsmie.czx

• Ani jedna z uvedených domén neexistuje

• Špatné rodné číslo (i když formát zápisu je v pořádku):

–561332/1234

• Špatná IP adresa (i když formát zápisu je v pořádku):

–192.168.0.315

Dílčí závěry

1. Spousta věcí vypadá jednoduše, ale má-li být popsána přesně, je to složité (viz RFC)

–Počítač (stroj) ale potřebuje přesný popis, který zahrnuje všechny možnosti (i výjimečné)

2. Pro funkční komunikaci dvou programů je důležité, aby byla ustanovena pravidla komunikace

–Protokol (síťový), rozhraní (API), formát (souboru)

3. Kontrola (validace) vstupů od uživatele je těžká

–Programátor může snadno udělat chybu

• Nemalá část bezpečnostních chyb je tohoto typu

–Rada: použít knihovny, kde už je toto naprogramované

4. Samotná kontrola syntaxe nemusí stačit

–Někdy může být nutná i kontrola „významu“

 

 

 

 

 


Syntaktická analýza
(parsing)

 

Syntaxe vs. sémantika(C#)

Syntakticky je program v pořádku, ale proměnná „pocet“ není nikde použita.

Syntakticky je program v pořádku, ale proměnná „vtup“ (překlep) neexistuje.

NÁSTROJE

IDE

•Integrateddevelopmentenvironment(IDE)= integrované* prostředí pro vývoj (software)

• Může zahrnovat:

–Editor kódu (zvýrazňování syntaxe aj.)

• Prohlížeč objektů, prohlížeč hierarchie tříd, …

–Překladač / interpret

• Nástroje pro řízení překladu (různé platformy atd.)

–Nástroje pro ladění (debugger)

–Nástroje pro návrh GUI, testování, …

• Příklady pokročilých funkcí viz např. http://www.microsoft.com/visualstudio/cze/products/compare#feature-chart- heading

* Integrovaný = tvořící vzájemně propojený funkční celek

IDE (příklady)

• VisualStudio (Microsoft)

• Eclipse

• IntelliJIDEA


 

• NetBeans

• JDeveloper(Oracle)

• Starší:

–Turbo Pascal, Delphi, C++Builder(Borland), …

Editor kódu

• Zvýrazňování syntaxe

• Doplňování kódu

• Propojení s nápovědou

–F1 zobrazí nápovědu dle kontextu (pozice kurzoru)

• Dále:

–Operace ve více souborech najednou

–Pokročilé vyhledávání (např. regulární výrazy)

–Refactoringkódu

Zvýrazňování syntaxe(syntax highlighting)

Různé syntaktické prvky (proměnné, klíčová slova, textové řetězce atd.) mají různý vzhled, typicky různou barvu písma.

Doplňování kódu(codecompletition)


 

 

 

Napovídání názvů proměnných, funkcí, metod atd. podle kontextu (souvislostí), popř. včetně vysvětlivek. Regulární výrazy(regularexpressions)

• Speciální „vzory“ (zápisy) pro vyhledávání složitějších textových výrazů

–Existují různé jazyky pro zápis regulárních výrazů (POSIXové/Unixovéregulární výrazy, Perlovskéregulární výrazy, …)

• Příklady:

Regulární výraz                                                                      Vyhledá

Agent 00[1-7]                                                                                                   Agent 001, Agent 002, …, Agent 007

Colou?r                                                                                                               Color, Colour

Hurá+                                                                                     Hurá, Huráá, Hurááá, Huráááá,…

([A-Z]):\1                                                                                                          A:A,B:B, C:C, D:D, E:E, …

 

Návrh GUI

Debugger

• Nástroj (program) pro hledání chyb vprogramech (bug= chyba)

–Podrobněji na příští přednášce

IDE není vše

• Pro práci (zejména) v týmu se hodí nástroje pro:

–Řízení týmových projektů

• Plánování (dle různých metodik), správa členů projektu, sledování průběhu, vykazování,

• Komunikace členů týmu (text, hlas, video)

–Sdílení a správu verzí (zdrojových kódů aj.)

–Správu sestavení (build)

–Správu testování

–Správa dokumentace (generování částí dokumentace)

–Modelování, diagnostiku, nasazení/publikování, …


 

• Příklad komplexnějšího nástroje:

–Team FoundationServer (Microsoft)

• http://www.visualstudio.com/cs-cz/products/tfs-overview-vs#Fragment_ProductFeatures

Správa verzí(versioncontrol, revisioncontrol)

• Správa změn ve zdrojových kódech programu

–Popř. i v dokumentaci, konfiguračních souborech, datových zdrojích atd.

• Příklady výhod:

–Řízení přístupu více programátorů k jednomu kódu

–Možnost návratu ke starší verzi kódu

• Např. „ještě včera to fungovalo“

–Možnost souběžného vývoje dvou (více) verzí programu

• Např. ve „stabilní“ verzi se opravují chyby, zatímco ve „vývojové“ verzi už se zkoušejí nové funkce

• Příklady specializovaných programů:

–CVS (ConcurrentVersionsSystem), Subversion(svn), Git, Mercurial, Microsoft VisualSourceSafe, …

Generování dokumentace

• Nástroje, které z komentářů ve zdrojovém kódu umí vygenerovat (část) dokumentace

–Dokumentační komentáře musí dodržovat určitá pravidla zápisu (aby se odlišily od běžných komentářů)

–Výsledná dokumentace může být provázána hypertextovými odkazy (formát HTML)

–Příklady: Javadoc(Java), Doxygen(C++, Java, PHP, Python, …)

• Příklad zdrojového kódu s dokumentačními komentáři:

–http://www.docjar.net/html/api/java/util/Collections.java.html

• Příklad vygenerované dokumentace:

–http://docs.oracle.com/javase/7/docs/api/

• Vlevo nahoře klikněte na java.utila pak vlevo dole v části Classesna Collections:vpravo bude odpovídající

dokumentace

PLATFORMA

Platforma (počítačová)

• Souhrn prostředků (HW i SW), které slouží jako „základna“ pro běh programů

• Může zahrnovat:

–Hardware, zejména procesor

• Jakou instrukční sadu používá

–Operační systém

• Které funkce, resp. systémové knihovny program vyžaduje

–Aplikační prostředí

• Např. framework, který program využívá

Platforma (dle procesoru)

• IA-32 (Intel Architecture, 32-bit), též x86

–Pojmenování „x86“ vychází z označení prvních Intel procesorů této architektury: 80286, 80386, 80486

–Nejen Intel, ale i AMD, VIA Technologies nebo Transmeta

• IA-64 (Intel Architecture, 64-bit)

–Intel Itanium(od roku 2001), hlavně servery

• Podporuje např. Windows XP 64-bit Edition

• x86-64, též x64, AMD64, Intel 64

–64bitové rozšíření instrukční sady IA-32

–Většina dnešních „běžných“ počítačů

• Architektura ARM (mobilní telefony, televize, …)

• Herní konzole (Playstation, Xbox, Wii, …)

• PowerPC(Apple Macintosh do roku 2006, nyní už x86)

• Speciální počítače (mainframe, superpočítače, …)

Platforma (hardware)

• Nejen instrukční sada procesoru, ale i:

–Výkon procesoru / grafické karty

–Množství dostupné paměti (RAM, HDD)

–Možnosti výstupních zařízení

• Rozlišení a poměr stran displeje, max. počet barev

–Možnosti vstupních zařízení

• Klávesnice / dotykový displej / hardwarová tlačítka / polohovací zařízení (myš, touchpad, Kinect, …)

• U různých stolních počítačů můžou být tyto charakteristiky podobné, ale u herních zařízení (konzolí) a přenosných zařízení (chytrých telefonů, tabletů) už je situace značně odlišná

Platforma (operační systém)

• Windows (Microsoft)

• Mac OS (Apple)

• Linux, FreeBSD, …


 

• Unix, Solaris, OS/2, AmigaOS, …

• Mobilní telefony:

–Android (Google)

–iOS(Apple)

–Windows Phone(Microsoft)

–BlackBerryOS

–Symbian(Nokia)

Framework (software)

• Knihovna funkcí, které tvoří základ pro vývoj software

–Obvykle obecné funkce, často i obecná „kostra“ programu –funkce specifické pro cílovou aplikaci nutno

doprogramovat

• Příklady frameworkůpro tvorbu webových aplikací:

–jQuery(Javascript), NetteFramework (PHP), ZendFramework (PHP), Ruby on Rails, ASP.NET MVC Framework, Spring(Java), Django(Python)

Platforma (aplikační prostředí)

• .NET Framework (Microsoft), Mono (open sourceimplementace)

• Java platform

• Adobe Flash, Adobe Shockware, Adobe AIR

• Silverlight(Microsoft)

• Qt, GTK (tvorba GUI)

Chyby

Co je to chyba?

• Dva pohledy:

–Programátor: co je v rozporu se specifikací programu

–Uživatel: co funguje jinak, než by chtěl

• Ideální by bylo mít tyto pohledy v souladu (tj. aby specifikace zachycovala to, co uživatel chce)

–Ale ne vždy se to podaří

• Může dojít i k hádkám o to, zda dané chování programu je chyba, nebo ne (tedy kdo zaplatí opravu)

Běžné příčiny chyb

• Člověk(aneb každý dělá chyby)

–Co zvyšuje míru chyb?

• Nedostatečná kvalifikace a/nebo zkušenost

• Časový tlak (honí se termín)

• Únava (přepracování)

• Špatné pracovní prostředí (vyrušování, nepohodlná židle, velká teplota v místnosti, nedostatek tekutin, špatné osvětlení, …)

• Malá motivace (např. nezáleží mu na kvalitě)

• Mimopracovní (např. rodinné) problémy

• Komunikace (mezilidská)

–Zadavatel ↔ realizátor

–Vedoucí týmu ↔ programátor

Špatná analýza požadavků

–Podcenění složitosti projektu

• Z toho plynoucí časový tlak, přepracování, …

–Nedostatky v zadání

• Aplikace je perfektní (dle zadání), ale skuteční uživatelé chtěli (potřebovali) něco jiného

• Nové technologie

–Nevyzkoušené funkce nebo celé knihovny

• Chvíli trvá, než se programátor s novou technologií seznámí a než ji umí správně použít

• Nové projekty obsahují větší míru chyb (tvůrce se v prvotních fázích soustředí na funkce, projekt není otestován na velkém vzorku uživatelů), dokumentace může být nedostatečná, …

Běžné typy chyb (technicky)

• Aritmetické chyby

• Logické chyby

• Jazykové omyly

• Chybná práce s pamětí

–Přetečení zásobníku, únik paměti

• Chyby souběžných systémů

–Deadlock, racecondition

• Další chyby

–Výkon, rozhraní, tým

Aritmetické chyby

• Dělení nulou


 

• Přetečení (overflow)

–intx = 300000; // Int32inty = x * x; // y je −194313216;

• Zaokrouhlovací chyby

–double x = 0.1; double y = (0.1 + 10) -10;Console.Write(x == y); // False

Logické chyby

• Chyba „plus/minus 1“

–Příklad:Mějme čísla 7, 8, 9, …, 22, kolik těch čísel je?22 − 7 = 15?Kdepak, je jich 22 − 7 + 1 = 16.

• Nekonečný cyklus

–// v cyklu zapomeneme zvýšit// proměnnou i o jednainti = 1;while(i != count){………}

• Nebo omylem nastavíme countna záporné číslo

• Operátor !=znamená nerovnost (opak ==)

• Nekonečná rekurze

Jazykový omyl

• if(x = 5) …

–Neprovede test, zda je hodnota proměnné xrovná 5 (to by v závorce muselo být x == 5), ale provede přiřazení hodnoty 5 do proměnné x

Chybná práce s pamětí

• Častá u jazyků, které umožňují přímou práci s pamětí (např. jazyky C, C++)

• Přetečení zásobníku (bufferoverflow)

–Program požádá operační systém o 16 bajtů paměti.Omylem do paměti zapíše 17 bajtů.Zápis posledního bajtu může způsobit:

• Chybu v přístupu do paměti (porušení přístupových práv), což typicky znamená pád programu

• Přepis tam uložené hodnoty (např. proměnné), což může vyústit vprakticky cokoli (divné chování programu, pád programu, …)

–Pokud jsou zapisovaná data (17 bajtů) pod kontrolou uživatele (jde např. o zadávaný vstup), pak lze často tuto chybu využít k narušení bezpečnosti daného programu

Chybná práce s pamětí

• Únik paměti (memoryleak)

–Program požádá OS o 1 MB paměti.Později program tuto paměť přestane využívat, ale zapomene ji „vrátit“.

• Pokud program takto žádá o paměť (a nevrací ji) opakovaně, pak program zabírá v operační paměti stále více a více místa… (až místo dojde)

Příklad: Mozilla Firefoxverze 15 (z 28. 8. 2012) obsahuje funkci, která zmírňuje dopady úniků paměti zásuvných modulů (plug-inů). Vývojáři Firefoxutotiž zjistili, že úniky paměti způsobují z velké části právě zásuvné moduly (tj. cizí programy), ne samotný Firefox. Podrobnosti viz http://blog.mozilla.org/nnethercote/2012/07/19/firefox-15-plugs-the- add-on-leaks/

Chyby souběžných systémů

• Chyby, ke kterým může dojít v případě, kdy běží více programů (popř. vláken*) najednou

–Víceprocesorové počítače (multiprocessing)

–Víceúlohovéoperační systémy (multitasking)

–Vícevláknovéprogramy (multithreading)

–Distribuované systémy

• Programy běží na různých počítačích, ale používají společné zdroje (zejména paměť)

• Příklady chyb:

–Dead-lock(uváznutí)

–Racecondition(souběh)

• Řešení:

–Synchronizace (koordinace běhu)

*  Vlákno (thread) je část programu (tj. posloupnost instrukcí), která může běžet samostatně

Deadlock, racecondition

• Deadlock(uváznutí)

–Program A čeká, až program B dokončí nějakou akci. Zároveň ale program B čeká na dokončení akce programu A

• Takto může čekat i více programů

–Výsledek: Všechny programy „zamrznou“

• Racecondition(souběh)

–Chyba, kdy výsledky závisí na načasování jednotlivých instrukcí programu

–Typický výsledek: někdy se stane něco jiného, než co programátor očekává Racecondition(příklad)

• Program zvyšující čítač X:


 

–Načti X (z databáze, ze souboru, z paměti)X = X+ 1Ulož X

• Při vícenásobném souběžném použití (spuštění) programu ale může nastat tato situace:

–Kód byl proveden 2×

–Ale čítač byl zvýšen jen 1×

Čas

X

Program1

Program 2

1

50

 

Načti X (50)

2

50

 

X =X+ 1 (51)

3

50

 

Načti X (50)

4

50

 

Ulož X (51)

5

51

 

X =X + 1 (51)

6

51

 

Ulož X (51)

7

 

51

 

Další chyby

• Chyby ve výkonu programu

–Nadměrné využití procesoru nebo paměti

• Závisí na zvolených datových strukturách a algoritmech

• Chyby při použití rozhraní

–Nesprávné použití API

–Nesprávná implementace síťového protokolu

• Chyby související s prací v týmu

–Např. nesprávné informace (komentáře v kódu, dokumentace, popis API)

• Zastaralé, nekompletní nebo zavádějící informace

Formální analýza kódu

• Nápad: Co udělat program Tester, který zkontroluje můj program (např. jeho zdrojový kód), zda je v pořádku?

• Problémy:

–U netriviálních programů existuje velké množství různých vstupů (a velké množství „průchodů“ programem) kontrola všech možností by zabrala hrozně moc času (miliardu let?)

–Program Tester, který by zkontroloval správnost výsledku, obecně nelze vytvořit

• Nelze totiž vytvořit ani jednodušší program –takový, který zjistí, jestli vůbec můj program vydá nějaký výsledek, tj. jestli můj program vůbec skončí (jde o tzv. problém zastavení)

Problém zastavení (haltingproblem)

• Lze udělat obecný program Tester, který rozhodne, zda se program P se vstupem V zastaví (nebo zda poběží donekonečna)?

–Vstupy: P (kód programu), V (vstupy programu P)

–Výstup: „Ano“ (program P se na vstupu V zastaví), nebo „Ne“ (nezastaví)

• Alan Turing(1936): Ne

–Tedy ani tak jednoduchý problém nelze vyřešit (označuje se za nerozhodnutelný)

• Jinými slovy: zacyklení programu není algoritmicky detekovatelné (a to ani v případě, že známe všechny vstupy

programu)

Reprezentace (odbočka)

• Základní myšlenka: Vše v počítači můžeme považovat za číslo

–Vše má v počítači binární reprezentaci, což je v podstatě jen zápis čísla (i když někdy obrovského čísla, s mnoha a

mnoha ciframi)

• Např. text tvořený 8 znaky je (při použití 1bajtového kódování znaků) vlastně 8bajtové číslo

• Např. rastrový obrázek tvořený 4 ×4 = 16 pixely je (při barevné hloubce 3 bajty) vlastně 48bajtové číslo

–Tedyvšechny vstupy(parametry) programu, výstupyprogramu i programsamotný (ať už zdrojový kód, tj. text, nebo binární kód) jsou jedna a tatáž věc, číslo (liší se jen hodnotou)

Problém zastavení (důkaz 1/3)

• Důkaz sporem:

–Předpokládám opak a dojdu k nesmyslnému výsledku (ke sporu)

• Tedy nechť program Testerexistuje

–Tester(X, V) tedy vrátí „Ano“, když program X se vstupem V skončí (jinak vrátí „Ne“)

Problém zastavení (důkaz 2/3)

• Vyrobím program AntiTesters jediným vstupem X

–Program AntiTesterbude fungovat takto:

• Spustí program Tester(X, X)a dále:

–Když je návratová hodnota „Ano“ (= program X se vstupem X skončí), tak se program AntiTesterúmyslně zacyklí (neskončí)

–Když je návratová hodnota „Ne“ (= program X se vstupem X neskončí), tak program AntiTesterskončí (s libovolnou návratovou hodnotou)

Problém zastavení (důkaz 3/3)

• Co se ale stane, když spustím program AntiTesterse vstupem AntiTester?

–Může buď skončit, nebo neskončit (zacyklit se)


 

a) Když AntiTesterskončí, tak dle definice AntiTesterumuselo dojít k situaci, že volání Tester(AntiTester, AntiTester)vrátilo „Ne“, což ale znamená (dle definice programu Tester), že program AntiTestersparametrem AntiTesterneskončí, tedy spor s předpokladem a)

b) Když AntiTesterneskončí, tak dle definice AntiTesterumuselo dojít k situaci, že volání Tester(AntiTester, AntiTester)vrátilo „Ano“, což ale znamená (dle definice programu Tester), že program AntiTestersparametrem AntiTesterskončí, tedy spor s předpokladem b)

–V obou případech jsme došli ke sporu, tedy náš předpoklad (že program Testerexistuje) musel být mylný

Jak chyby odhalovat? (1/2)

• Překladač

–Odhalí syntaktické chyby

–Odhalí některé sémantické chyby (nepoužitá proměnná apod.)

• Tracing(logging)

–Výpisy (na obrazovku, do souboru), které informují o stavu programu

• Post-mortemdebugging(„po smrti“)

–Při „pádu“ programu může operační systém uložit obsah paměti programu (v okamžiku pádu) do souboru (dumpfile,

crashdump)

• Lze později obsah souboru analyzovat: zjistit stav programu (hodnoty proměnných, na kterém příkazu program zhavaroval, s jakými parametry byla daná funkce volána atd.) v okamžiku pádu

• Krokování, breakpoint(viz dále)

Jak chyby odhalovat? (2/2)

• Defenzivní programování(„obranné“)

–Programování dle hesla „nevěř nikomu“ (ani sobě

–Např. důsledná kontrola všech vstupních hodnot funkce

• Často se využívá assertions(viz dále)

• Testování

–Spustím výslednou aplikaci a zkouším všechny funkce, různé divné vstupy atd. a sleduji, zda se program nechová nestandardně (špatné výsledky, spadne atd.)

–Napíšu si program, který testování udělá za mě (lze volat různé funkce programu s různými parametry, lze

„naskriptovat“ i klikání v GUI)

• Napsané testy lze hromadně spouštět po každé změně kódu a kontrolovat tak, zda změna něco „nerozbila“

• Unit testing= testování nezávislých částí (jednotek) programu (kódu)

Assertion

• Výraz typu ano/ne, kterým programátor vyjadřuje své očekávání (předpoklad)

–Pokud výraz neplatí, je program ukončen

• Příklad použití:

Pozor: Assertionneslouží pro zvládnutí „chyb“ uživatele programu, když např. uživatel zadá „divný“ vstup –na chyby uživatele totiž neumí assertionnijak rozumně reagovat (nemá žádné tělo). Assertionslouží pro odhalování chyb programátora, např. nesprávné volání funkce, neohlídání si určité krajní situace apod.

Krokování, breakpoint

• Krokování

–Provádění programu krok po kroku (příkaz po příkazu)

• Lze si prohlédnout stav programu (např. hodnoty proměnných) v daném okamžiku

• Breakpoint

–Místo (point) v kódu programu, kde se má běh programu zastavit (break)

• Lze dále provádění programu krokovat

Co s nalezenou chybou udělat?

• Co je to za divná otázka, existují snad důvody, proč nalezenou chybu neopravit?

• Ano, existují:

–Oprava chyby může do programu zavléct jinou, mnohem závažnější chybu

• Např. vyřeším špatné zobrazování ikony, ale program začne padat

–Oprava chyby stojí čas a programátory (tj. peníze)

• A taky s vydáním Windows 95 nelze čekat až do roku 1997

„Bug bar“ (laťka pro chyby)

• Příklad:

–Na začátku projektu je laťka na nule:

• Opravují se všechny chyby, které jsou nahlášeny

–Termín odevzdání projektu se blíží, takže „zvedáme laťku“:

• Opravují se jen chyby, které způsobují ztrátu dat uživatele (nebo horší)

–Termín se ještě více blíží, takže „zvedáme laťku“:


 

• Opravují se jen chyby, které znamenají smrt člověka* –Termín už je za dveřmi, takže „zvedáme laťku“:

• Opravují se jen chyby, které znamenají smrt blonďatých modrookých holčiček**

*  V řadě oblastí (lékařství, vojenství, fyzikální nebo chemické pokusy, řízení strojů atd.) se tohle skutečně může stát

** Tohle už je vtip

Program s chybami

• Je tedy zcela běžné, že firma vydá program, který obsahuje chyby, o kterých firma ví –Mělo by ale jít o méně závažné chyby

• Uživatel se často smíří s pár menšími chybami, pokud má program pro něj znatelný přínos

Například program Microsoft Word má v některých situacích problémy svykreslováním dokumentu (např. některé řádky jsou vidět „dvojmo“), ale stačí posuvníkempohnout nahoru a dolů a chyba je pryč. Jde tedy o malou chybu a obecně má pro mě tento program velký přínos, takže jsem ve výsledku spokojen.

Bug (issue) trackingsystem

• Aplikace pro evidenci chyb (požadavků*) –Zadávání chyb

• Prostředek pro komunikaci mezi zákazníky (zadavateli chyb), vývojáři (programátory), vedoucími projektů, … –Sledování stavu chyb

• Přiřazování chyb vývojářům, sledování počtu chyb, nastavování priority chyb, přístupová práva k popisům chyb (bezpečnostní chyby)

• Příklady:

–Bugzilla, Mantis, …

*  Požadavky jsou i návrhy na vylepšení, nejen chyby

Jak hlásit chyby?

• Co má obsahovat popis chyby?

• Odpověď získáme, když se zeptáme: K čemu se popis chyby použije?

–Typicky se programátor bude snažit podle toho popisu chybu znovu vyvolat –aby ji mohl prozkoumat

Jak hlásit chyby?

• Popis chyby by tedy měl obsahovat:

–Popis situace popř. aktivity tak, aby bylo možné chybu znovu vyvolat (zreprodukovat)

• Typicky kroky, které k chybě vedou

• Okolnosti (použitý program, platforma atd.)

–Např. řada uživatelů Windows zapomene zmínit, že používají Windows (když chyba může být závislá na operačním systému)

–Popis, jak by to mělo být správně

• Ne vždy je jasné, co přesně uživateli na popsané situaci vadí, nebo jakou změnu udělat, aby to už uživateli nevadilo.

Programovací paradigma

Historie programovacích jazyků(pro základní přehled)Éra      Jazyky vzniklé v dané éře

50.a 60. léta                                                                          FORTRAN, LISP, COBOL, ALGOL,BASIC

1968-1979                                                                                                      Simula(OOP), Logo, Pascal

C(DennisRitchie, KenThompson) Smalltalk, Prolog, Scheme

80. léta                                                                                 C++, Objective-C

Eiffel, Erlang, Perl

90.  léta                                                                                 Haskell, Python, VisualBasic, Ruby, Lua

Java, Delphi(ObjectPascal)

JavaScript, PHP

2000 a později                                                                        ActionScript(FlashPlayer), C#, Clojure,Dart

Úroveň programovacího jazyka

• Nižší (nízkoúrovňový, low-level, strojově orientovaný) jazyk

–Žádná nebo malá míra abstrakce od hardware (procesoru), tj. těsně spjatý s hardware

• Překlad do strojového kódu typu 1 : 1 (jeden příkaz jazyka odpovídá jedné strojové instrukci)

–Např. strojový kód, assembler

• Vyšší (vysokoúrovňový, high-level) jazyk

–Vyšší míra abstrakce

• Překlad typu 1 : N (jeden příkaz odpovídá více instrukcím)

–Např. vše ostatní

Nižší vs. vyšší (+/−)

• Výhody nižších jazyků:

–V některých situacích (jednoduché čipy, robůtci atd.) jediná možnost programování

• Není-li dostupný překladač/interpret

–Větší výkon programu


 

• Nižší nebo žádná režie (žádné zbytečné instrukce) –Větší kontrola nad tím, co program dělá

• Výhody vyšších jazyků:

–Jednodušší (tj. levnější) tvorba programů

• Jazyky obsahují prostředky usnadňující programování: proměnné, datové struktury, řídící struktury, metody, objekty,

–Lepší přenositelnost programů

• Funkčnost programů na širší skupině hardware

Programovací paradigma

• Paradigma:

–Příklad, vzor

–Soubor předpokladů, na kterých je vybudována určitá teorie

–Způsob pohledu na určité jevy z pozic ucelené teorie

–Soubor předpokladů vytvářející rámec pro existenci určitého jevu

• Programovací paradigma

–Základní programovací styl

Programovací paradigmata

• Imperativní (příkazové)

–Nestrukturované (např. BASIC)

–Strukturované

• Procedurální (např. Pascal, C)

• Objektově orientované (Java, C++, Objective-C, C#, …)

• Deklarativní

–Logické (např. Prolog)

–Funkcionální (např. Lisp, Scheme, Haskell)

Řada jazyků podporuje několik paradigmat zároveň ČLOVĚK

Deklarativní (logický nebo funkcionální) jazyk

• Příkazový objektový: C++, Python, C#, Java

• Příkazový strukturovaný: Pascal, C

• Příkazový nestrukturovaný: BASIC

• Jazyk symbolických instrukcí (assembler)

• Strojový kód

STROJ

Každý jazyk má své výhody a nevýhody, tj. neexistuje „obecně nejlepší“ jazyk, může však existovat jazyk nejlepší pro danou situaci, pro dané použití

Ukážeme si

Strojový kód

• Instrukce pro hardware (procesor)

• Typy instrukcí (vonNeumann):

Součástka                           Funkce(které instrukce umí provést)

Procesor –řídící jednotka         Dekóduje instrukce, úkoluje ostatní jednotky

Instrukce skoku (jump)

Procesor –ALU                               Aritmetické (+ − · / …) a logické (=< AND NOT XOR

…)instrukce

Paměť(operační)                    Instrukce zápisu dopaměti (write, store) a načítání (read, load)

z paměti

Vstupní a výstupní jednotky     Instrukce čtenídat ze vstupů a posílání dat na výstup

 

Registry procesoru

• Paměti přímo v procesoru

–Malé paměti

• Např. architektura x86 používá několik desítek 32bitových registrů, tj. celkem desítky bajtů (naproti tomu RAM má miliardy bajtů)

–Velice rychlé paměti

–Používají se jako vstupy a výstupy při provádění instrukcí

• Např. instrukce sčítání: oba sčítanci jsou v nějakých registrech a výsledek (součet) se také uloží do registru

–Pro práci s registry se obvykle používají jiné instrukce než pro práci s operační pamětí

• Jednotlivé registry jsou identifikovány např. svým pořadovým číslem

Práce s operační pamětí

• Paměť je rozdělena na „přihrádky“ pevné velikosti (např. 1 bajt)

–Přihrádku lze identifikovat pomocí jejího pořadového čísla, tzv. adresy

• Instrukce zápisu do paměti má dva parametry:

–Adresa (kam zapisovat)


 

–Data (co zapsat)

• Instrukce čtení z paměti má dva parametry:

–Adresa (odkud číst)

–Kam uložit načtená data (např. do kterého registru)

Adresa                …       834       835       836      837       838       839       …

Hodnota (16)      4D       41          68          6F          6A          00          6B          23

Ukázka: architektura MIPS I

• Procesor má 32 registrů

–Na identifikaci registru tedy stačí 5 bitů (25= 32)

• Každá instrukce má 32 bitů

–Příklad instrukce (mezerami jsou odděleny jednotlivé logické části instrukce):000000 00100 00101 00010 00000

100000

Význam instrukce: Hodnota opcode(nejvyšších 6 bitů instrukce: 000000) určuje, že jde o instrukci, která má pět parametrů: tři 5bitové identifikátory registrů (rs, rt, rd), 5bitová velikost posunu (shamt) a 6bitové upřesnění funkce (funct). Hodnota funct(100000) určuje, že jde o operaci sčítání registrů. Sčítanci jsou v registrech č. 4 a 5 (rs: 00100, rt: 00101), výsledek sčítání se má uložit do registru č. 2 (rd: 00010). Hodnota posunu (shamt) se u operace sčítání registrů ignoruje. Smysl této instrukce by se tedy dal symbolicky zapsat takto: reg2 = reg4 + reg5

Strojový kód (+/−)

• Výhody:

–Někdy jediná možnost programování

–Možnost maximálního výkonu programu

–Maximální kontrola nad tím, co program dělá

• Nevýhody:

–Náročná tvorba programů (primitivní prostředky)

–Nepřenositelnost programů (obecně)

• Použití:

–Jednoduché čipy, robůtci, hardware obecně

Jazyk symbolických adres (assembler)

• Textový zápis jednotlivých strojových instrukcí

–Druh operace slovně, např. mov= operace přesunu dat (move)

–Identifikace registru názvem, např. registr eax(místo 00001)

–Pro číselné hodnoty lze použít desítkový nebo šestnáctkový zápis (místo binárního)

• Trochu matoucí terminologie (v praxi):

Programovací jazyk                                                               Program pro převod do strojového kódu

Anglicky (teoreticky)                                        Assemblylanguage                                                 Assembler


 

Česky(teoreticky)                                   Jazyk symbolických adres (jazyk symbolických instrukcí)


 

Assembler


 

Česky(prakticky)                                                Assembler                                                                Překladač

Odbočka: reprezentace stringů

• Textové řetězce (string) můžou být různě dlouhé (různý počet znaků/bajtů) –Jak poznat, kde (v paměti) řetězec končí?

• Obvykle se používá jedno z následujících řešení:

–Ukládá se i délka řetězce

• Použití: jazyk Pascal (první bajt textu = délka)

• Nevýhoda: řetězec má omezenou délku (255 znaků)

–Použije se značka, která znamená „konec textu“

• Např. bajt s hodnotou nula (00000000)

• Použití: jazyk C

• Nevýhoda: uvnitř řetězce se daná značka nesmí vyskytovat

Ukázka: assembler x86

; counts a zero terminated ASCII string

; to determine its size

; in: eax= start address of the string

; out: ecx= the length of the string

zstr_count: movecx, -1

.loop:

incecx

cmpBYTE [eax+ ecx], 0

jne.loop

.done:

Ret

Ukázka: assembler x86


 

Zjistí délku textového řetězce, kde ukončovacím znakem je znak s ASCII kódem 0 (nula)


Vstup: V registru eaxje uložena adresa začátku (1. znaku) textového řetězce Výstup: Na konci má být v registru ecxvýsledek (délka)

 

Ukázka: assembler x86

 

 

 

 

 

 

Assembler (+/−)

• Výhody oproti strojovému kódu:

–Jednodušší tvorba programů –přehlednější (textový) zápis

• Nevýhody oproti strojovému kódu :

–Nutnost překladače do strojového kódu

• Použití:

–Jednoduché čipy, robůtci, hardware obecně (ovladače zařízení, firmware, BIOS, čipy v pračkách, autech, senzorech

atd.)

–Když je kriticky důležitý výkon (vědecké výpočty, real-timesystémy, real-timehry, dekódování videa, šifrování, komprese dat, …)

–Když je důležitá maximální kontrola nad činností programu (simulátory, virtualizace, debuggery, reverzní inženýrství,

sebe-modifikující programy, viry, …)

Příkazové programování

• Je bližší člověku (jeho myšlení) než assembler

–Proměnné (a někdy i datové typy)

–Řídící struktury: cykly (FOR), podmínky (IF), …

–Složitější výrazy (x + 5 >= (y + 7) * z)

• Implementace (principiálně):

–Proměnné = instrukce zápisu do (čtení z) paměti

–Řídící struktury = instrukce skoku

–Složitější výrazy = posloupnost více instrukcí Ukázka: BASIC


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ukázka: BASIC

• Příklad běhu programu:

What is your name: Mike Hello Mike

How many stars do you want: 7

*******

Do you want more stars? yes How many stars do you want: 3

***

Do you want more stars? no Goodbye Mike

Poznámka: Ukázka odpovídá první generaci jazyka BASIC. V dalších generacích došlo k vylepšení jazyka o prvky strukturovaného a později i objektového (např. VisualBasic .NET) programování, také byla odstraněna nutnost číslování řádků.

Příkazové nestrukturované (+/−)

• Výhody oproti assembleru:

–Jednodušší tvorba programů –proměnné (popř. datové typy), řídící struktury (FOR, IF, …), výrazy

• Nevýhody oproti assembleru:

–Překladač pro příkazový jazyk je složitější než pro assembler (překlad bude typu 1 : N), tzn. je menší šance, že bude

existovat

• Použití:

–Historie

–Dnes už je prakticky každý příkazový jazyk strukturovaný

Procedurální programování

Procedurální programování

–Algoritmus

–Proměnné a datové typy

• Typová kontrola, oblast platnosti, inicializace

–Metody (funkce a procedury)

• Parametry (předávání), návratová hodnota

• Návrh metody

Algoritmus


 

• Algoritmus = postup řešení problému

• Vlastnosti algoritmu:

–Hromadnost(obecnost)

• Neřeší jeden konkrétní problém (např. největší společný dělitel čísel 35 a 20), ale celou třídu podobných problémů (např. největší společný dělitel čísel x a y)

–Determinovanost

• Každý krok algoritmu je přesně určen (determinován)

• Existují ale i nedeterministické algoritmy (např. pravděpodobnostní algoritmy, které se v některých krocích rozhodují náhodně)

–Konečnost

• Algoritmus skončí po konečném počtu kroků

–Resultativnost

• Algoritmus má nějaký výsledek (výstup)

Algoritmus

• Zápis algoritmu:

–Přirozený jazyk

–Vývojový diagram

–Pseudojazyk

–Programovací jazyk

Vývojový diagram(algoritmus kontroly funkčnosti lampičky)

Rysy procedurálních jazyků

• Údaje = datové objekty

–Proměnná nebo konstanta

–Datový typ

• Programse skládá z deklarací a příkazů:

–Deklarace= určení významu identifikátorů (jmen)

–Příkazy= akce s datovými objekty nebo řízení výpočtu (větvení, cykly atd.)

PROMĚNNÉ A DATOVÉ TYPY

Datový typ

• Má vliv zejména na:

–Množství zabrané paměti(kolik bajtů)

• Může záviset na uložené hodnotě (např. u textových řetězců)

–Možné hodnoty

• Např. jaké je minimum a maximum u celých čísel, jaká je přesnost u čísel desetinných atd.

• Některé typy mají vnitřní strukturu (položky, členské proměnné, např. typ Zlomekmá položky Čitatela Jmenovatel)

–Možné operace

• Např. sčítání u čísel, spojení u textových řetězců atd.

• A také efektivita (časová, prostorová) provádění různých operací

Běžné datové typy I

• Základní datové typy (umí je hardware, tj.procesor, viz také registry):

–Celá čísla (int, integer)

• Obvykle 8/16/32/64 bitů (má vliv na rozsah hodnot)

• Se znaménkem (signed), nebo bez (unsigned)

• Odvozené typy (tj. jen „převlečený“ integer): boolean, char, výčtový typ (např. pohlaví: muž [0], žena [1], neurčeno

[2]), ukazatel(pointer)

–Čísla s desetinnou čárkou (float, double)

• Obvykle 32/64 bitů (IEEE 754)

Běžné datové typy II

• Složitější datové typy

–Pole(obvykle homogenní –prvky stejného typu), vektory, spojové seznamy, zásobníky, matice, hašovacítabulky, …


 

–Struktury(obsahují prvky různých typů)

• Často i uživatelsky definovatelné

–Textové řetězce (string)

• Pozor: různá implementace v různých jazycích (tj. různé vlastnosti)

–Velká (popř. neomezená) čísla

• Viz např. http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic#Languages

–Objekty/třídy(viz Objektově orientované program.dále)

–Funkce(viz Funkcionální programovánídále)

Typová kontrola

• U řady programovacích jazyků je nutné u proměnné uvést její datový typ a ve výrazech nelze (neomezeně) míchat různé datové typy

–Např. C, C++, Java, C#, Pascal, … (často kompilované jazyky)

• Říká se, že takový jazyk má statickoutypovou kontrolu (už při kompilaci) a že má silnétypování (nelze míchat odlišné typy)

–Umožňuje zachytit (typovou) chybu brzy

• U řady jiných jazyků se datový typ proměnné neuvádí a lze vjednom výrazu míchat různé datové typy (např. číslo a

text)

–Např. JavaScript, PHP, Python, … (často interpretované jazyky)

• Říká se, že takový jazyk má dynamickoutypovou kontrolu (až při běhu programu) a že má slabétypování

–Snadnější psaní kódu (není nutné uvádět datové typy proměnných a ručně provádět konverze mezi typy)

Typová kontrola (příklad 1)

x= "1" + 2

Typový systém

Silný                                 Chyba při překladu (u operace „plus“ nelzemíchat textový řetězec a číslo)

Slabý                                "12"(číslo 2 se automaticky převede na textový řetězeca provede se spojení řetězců),

nebo 3(řetězec "1" se automaticky převede na číslo a provede se sčítání)

 


 

Typová kontrola (příklad 2) if (x=5) …

Typový systém

Výraz „x=5“ má typ„celé číslo“ (a hodnotu 5). Konstrukce ifale vyžaduje logickou hodnotu (true/false).


 

Komentář


 

C,C++                                                                                   Jazyk provede u konstrukce ifautomaticképřetypování zcelého čísla na logickou hodnotu (nenulové číslo              true). Výše uvedený kód je tedy korektní a je ekvivalentní kódu: x=5; if(true) …

C#, Java                                                                               Jazyk neprovádí automatické přetypování zčíselné hodnoty na logickou. Výše uvedený kód tedy překladač označí jako chybný.

 

Typová kontrola (příklad 3)

Graf vlevo ukazuje, které hodnoty jsou si rovné (operátor ==) v jazyce PHP. Pokud budeme míchat různé datové typy (číslo, logickou hodnotu, textový řetězec), pak dojdeme k překvapivému zjištění, že1 == True== "php" == 0

Logika operátoru == přitom dává smysl:

Řetězec vs. logická hodnota:

"" (prázdný řetězec) == False "abc" (neprázdný) == True Řetězec vs. číslo:

"1" == 1

"2" == 2 atd.

"nečíslo" == 0

Pro test rovnosti hodnoty a zároveň i datového typu má jazyk PHP operátor === (3 rovnítka)

Proměnné a datové typy (ukázka)

Jazyk                            Kód              Poznámka


 

C, C++, Java, C#       intx= 5;

Pascal                           var

x: integer; y: char; begin

…

x = 5;

…

end


 

 

Deklaraci typů (část var) je nutné uvéstještě před tělem programu (část begin… end)


 

PHP                                $x = 5;             Proměnné sepoznají podle znaku $

Není nutné deklarovattyp

JavaScript,Python       x =5;                Není nutné deklarovattyp

 

Oblast platnosti proměnné

• Obecně:

–Lokální= platnost v omezené části kódu

–Globální= platnost v celém programu

• Různé jazyky ale lokálnost/globálnost chápou různě:

–Platnost v nějak vymezeném bloku kódu

–Platnost v jednom souboru

–Platnost v jednom modulu/unitu/balíčku (v jedné logickéjednotce programu)

–Jazyk PHP: explicitně globální proměnné (global$x) vs. implicitně globální (tzv. superglobální)

 

Vymezení bloku kódu (ukázka)Jazyk       Příklad kódu     Způsob vymezení


 

C, C++, Java, C#, PHP, JavaScript           {

…

}

Pascal                                                              begin

…

end

Python                                                             deffoo(x):

if x == 0: bar()

baz() else: qux(x) foo(x -1)


 

Speciálními znaky (složené závorky)

 

Klíčovými slovy (begin, end)

 

Odsazením jednotlivých řádků kódu


 

Životnost proměnné

• Jak proměnná (datový objekt) vznikne?

–Automaticky na začátku bloku, ve kterém je deklarovaná

• V některých jazycích až na řádku, kde je deklarovaná

–Ručně příslušným příkazem (např. new)

• Jak proměnná (datový objekt) zanikne?

–Automaticky na konci bloku

–Ručně příslušným příkazem (např. delete)

Inicializace proměnné

•Jakou hodnotu má proměnná na začátku?

–Námi definovanou (např. intx = 5;)

–Předem danou (viz specifikace daného jazyka)

• Obvykle nějakou neutrální, např. u čísel 0 (nula)

–Nedefinovanou (tj. libovolnou/náhodnou)

• Pokud jazyk povoluje použít neinicializovanou proměnnou (např. C, C++), pak je to poměrně nebezpečné

–U řady jazyků záleží i na datovém typu proměnné a také na tom, zda je proměnná lokální nebo globální

Identifikátory I

• Různé jazyky mají různá pravidla pro zápis identifikátorů (názvů proměnných, funkcí, datových typů atd.):

–Obvykle nesmí název začínat číslicí (aby se dal rozeznat od číselné konstanty)

• Případně se pro odlišení proměnné používá nějaký speciální znak (např. $)

–Záleží/nezáleží na velikosti písmen

–Název musí/nemusí začínat velkým/malým písmenem

–Jsou/nejsou povoleny znaky s diakritikou (á, č, ď, é, …)

–Které nepísmenné znaky jsou/nejsou povoleny (tečka, podtržítko, …)

Identifikátory II


 

• Pro dobrou čitelnost kódu je vhodné se držet zvyklostí daného jazyka (popř. dané knihovny, firemní kultury atd.) –Zápis může napovědět (rozlišovat), zda jde o proměnnou, konstantu, název funkce, název datového typu atd.

• Příklady zápisů:

old_HTML_file old-HTML-file OLD_HTML_FILE

oldHtmlFile OldHtmlFile

Některé typy zápisů mají i svůj název, např. Camelcasenebo Pascal case

Identifikátory III

• U rozsáhlých programů je problém, jak pojmenovat novou proměnnou (funkci, datový typ), aby nový název byl jedinečný (tj. nebyl stejný jako některý starý)

–Řešení č. 1: dlouhý název zahrnující např. i oblast užití proměnné (název části programu apod.), např.

SystemNumericsBigInteger

• Nepraktické –úmorné psaní, zmenšuje přehlednost kódu (moc dlouhé řádky/příkazy)

–Řešení č. 2: dlouhý strukturovanýnázev, např. System.Numerics.BigInteger

• Podpora: tzv. jmenný prostor (namespace)

Jmenný prostor (namespace)

• Skupina identifikátorů (nějak souvisejících)

• Příklad (C++): std::cout

–Existuje jmenný prostor „std“

• V něm existuje lokální identifikátor „cout“

• Příklad (C#): System.Numerics.BigInteger

–Existuje jmenný prostor „System“

• V něm existuje jmenný podprostor „Numerics“

–A v něm existuje lokální identifikátor „BigInteger“ Jmenný prostor (příklad, C#)

METODY

Návrh programu

• Rozdělit program na logické bloky (abstraktní příkazy), tzv. „metody“

–Každá metoda řeší nějaký podproblém

–Metody navzájem spolupracují

• Propojení metod: předáváním parametrů a návratových hodnot (popř. i jinak)

• Princip se označuje jako „Rozděl a panuj“ (latinsky divideet impera)

Metoda (vlastnosti)

• Co programátora na metodě zajímá?

–Vstupymetody

–Tělometody (tj. co metoda dělá)

• Někdy i náročnost (časová, paměťová)

–Výstupymetody

Vstupy a výstupy metody

• Vstupy metody:

–Parametrymetody

–Globální stav

• Globální proměnné

• Obsah paměti, disků (soubory), síťová komunikace, …

• Vstupní zařízení (myš, klávesnice, …)

• Výstupy metody:

–Návratová hodnota

–Výstupní parametry

–Změna globálního stavu (tzv. vedlejší efekty, side-effects)

• Glob. proměnné, paměť, zařízení (obrazovka, tiskárna, …)

Vstupy a výstupy: bestpractices


 

• Vstupymetody je nejlepší realizovat pomocí parametrů

–Protože parametry „jsou vidět“ (jak v deklaraci metody, tak při jejím volání)

–Že metoda čte i globální stav, to „vidět není“ (ani v deklaraci, ani při jejím volání)

• Je vhodné to tedy programátorovi sdělit jinak: názvem metody nebo to uvést v dokumentaci metody

• Výstupymetody je nejlepší realizovat pomocí návratové hodnoty

–Protože návratová hodnota „je vidět“ (viz výše)

–Pokud je výstupních údajů více, je možné použít vhodnou datovou strukturu nebo výstupní parametr(y)

–Změny globálního stavu (tzv. vedlejší efekty) „vidět nejsou“

• Sdělit jinak: názvem, v dokumentaci

Deklarace vs. definice metody

• Deklarace= určení, že daná metoda existuje

–Jaký má název

–Jaké má parametry (popř. jejich datový typ)

–Popř. jaký typ má návratová hodnota

–Popř. další vlastnosti*

• Definice= určení těla metody (co dělá)

• U některých jazyků lze deklaraci a definici uvést zvlášť (v různých částech kódu)

Funkce a procedura

• Některé jazyky (např. Pascal) rozlišují funkcia proceduru:

–Funkce má návratovou hodnotu

• Lze použít ve výrazu (např. if(max(x, y) > 5) …)

–Procedura nemá návratovou hodnotu

• Nelze ji použít ve výrazu

• Svůj výstup realizuje buď pomocí výstupních parametrů nebo změnou globálního stavu

• A v některých jazycích (C++, C#, PHP, …) je to jedno a obojímu se říká funkce

–Rozlišení se dělá např. speciálním typem návratové hodnoty (např. void)

 

Funkce (ukázka)Jazyk            Příklad kódu

C++, Java, C#                          intscitani(intx, inty)

{

return x + y;

}

Pascal                                          functionscitani(x: integer, y: integer): integer; begin

scitani:= x + y; end

Python                                        defscitani(x, y): return x + y

Procedura (ukázka)Jazyk       Příklad kódu

C++, Java, C#                          voidvypis(strings)

{

// vypisna obrazovku

}

Pascal                                          procedurevypis(s: string); begin

{vypisna obrazovku } end

Python                                        defvypis(s):

#vypisna obrazovku


 

Předávání parametrů metodám

• Hodnotou(by value)

–Vytvoří se kopie hodnoty parametru a metodě se předá tato kopie

• Hodnotu původního parametru tedy metoda změnit nemůže (pracuje jen s kopií)

• Typické pro paměťově nenáročné datové typy (integer, float)

• Odkazem(by reference)

–Metodě se předá odkaz (reference, adresa) na hodnotu parametru

• Metoda tedy může hodnotu změnit a tím parametr použít jako výstupní

• Typické pro paměťově náročné datové typy (pole, string, objekt atd.) –nemusí se kopírovat velké množství dat


 

Předávání parametrů (ukázka)Jazyk


 

 

Deklarace funkce


 

Volánífunkce


 

C++                                                                            voidfoo(int&x)

{

x = 5;

}

C#                                                                               voidfoo(outintx)

{

x = 5;

}


 

intdnt= 1; foo(dnt);

// nyní má dnthodnotu 5

 

intdnt= 1; foo(outdnt);

// nyní má dnthodnotu 5


 

Návrh metody (chyby 1)

Co je špatně?


Nicneříkající název funkce i proměnných, chybí komentář spopisem   není moc jasné, co funkce dělá a co se ve funkci děje Návrh metody (chyby 2)

 

 

 

 

Co je špatně?

Pro vstupy i výstupy jsou použity globální proměnné   při volání funkce není vidět, co vše funkce mění (vedlejší efekty); lepší je pro vstupy použít parametry a pro výstupy návratovou hodnotu

Návrh metody (chyby 3)

V pořádku

Návrh metody (chyby 4)


 

 

Kratší, ale méně přehledný zápis. Někteří programátoři argumentují, že tato verze bude rychlejší, ale nárůst rychlosti by ve většině případů byl nicotný a často vůbec žádný (optimalizaci dnes umí provést i kompilátor). Určitě doporučuji použít předchozí verzi, je srozumitelnější a lépe se ladí (můžu si výpočet lépe odkrokovat).

Návrh metody: zásady

• Pro opakované použití s různými daty

• Ověřit platnost vstupů

• Ne moc dlouhá

• Ne moc parametrů

• Vhodná jména: metody, parametrů, konstant


 

• Vstupy: použít parametry

• Výstupy: použít návratovou hodnotu –Nebo výstupní parametry

• Komentáře: metoda i programátorské obraty

• Vhodné formátování kódu

Výhody použití metod

• Přehlednost, lepší orientace v kódu

–Místo jednoho dlouhého seznamu příkazů mám příkazy rozdělené do pojmenovaných logických bloků

• Rozdělení práce

–Jeden velký problém rozdělím na řadu menších (jednodušších) podproblémů

• Snazší zvládnout (po částech)

• Lze rozdělit mezi různé programátory

• Znovupoužitelnost kódu

–Volání metody s různými parametry

• Ušetří opakované psaní stejného (podobného) kódu

• Snazší testování kódu (i krokování)

• Snazší změna kódu (oprava chyby): jen na jednom místě

Příkazové strukturované (+/−)

• Výhody oproti nestrukturovanému:

–Přehlednost, lepší orientace v kódu

–Rozdělení práce

–Znovupoužitelnost kódu

• Nevýhody oproti nestrukturovanému:

–Žádné

• Leda tak režie při předávání parametrů metodám (zejména při předávání hodnotou –kopírování dat)

• Použití:

–Jedno z nejběžnějších programovacích paradigmat

• Nicméně vhodnější je spíše pro programy menšího rozsahu (uvětšího rozsahu už se projevují výhody objektově

orientovaného programování)

OOP

Co OOP je a co není?

• Co OOP je?

–Programovací styl, filozofie, technologie

• Co OOP není?

–Není řešením všech programátorských problémů

–Není ve všech případech lepší než jiné techniky

Softwarová krize

• Čím dál větší závislost na počítačích

–Tedy inasoftware

–Velké množství chyb

–Náročné spravovat

–Náročné rozšiřovat

–Velké náklady

–Mnoho chyb

Znovupoužitelnost

• Inspirace: Stavebnictví

–Všechny domy využívají stejné cihly, tvárnice, šroubky, hřebíky, …

• Cíl: Vytvořit komponenty:

–Snadno pochopitelné a použitelné

–Znovupoužitelné pro různé případy

• Komponenty = základní stavební bloky

–Psát jen kód specifický pro danou aplikaci

Znovupoužitelnost komponent

• Levnější a rychlejší vývoj

–Méně psaní kódu, testování, psaní dokumentace

• Méně chyb v kódu

–Komponenta je využívána mnoha lidmi (a různými způsoby)    odhalení „provozních“ chyb

• Programátoři nemusí být experti na vše

–Lze využít už existující komponentu

• Větší motivace pro programátory (někdy)

–Bude to používat více lidí    programátoři více přemýšlejí nad návrhem komponenty (odpovědnost nebo ať si neudělají

ostudu)

Problémy a omezení strukturovaného programování I

• Sdílená nebo rovnou globální data

–V reálných (větších) programech jsou potřeba

–Ale tím je narušena modularita (nezávislost metod)    nepřehlednost, chyby

• Náročné přizpůsobení programu změnám

–Není žádný mechanismus, který by provádění změn usnadnil

• I menší změna často způsobí změny kódu na mnoha různých místech

–Nejdříve drobné úpravy, později„hacky“   nepřehlednost, nestabilita Problémy a omezení strukturovaného programování II

• Složitější datové struktury (zásobník, strom, …)

–Problémy s přístupem


 

• Nelze nijak chránit dílčí datové položky (prvky), cizí programátor může celou strukturu „rozbořit“ (např. omylem přiřadí hodnotu NULL tam, kam nemá)

• Přístup k datovým položkám není jednotný –někdy to lze přímo, někdy pomocí funkcí, někdy kombinace –Problémy s různými datovými typy ve struktuře

• Např. zásobník je principiálně jedna struktura, ale kvůli kontrole datových typů musím mít „zásobník pro int“, „zásobník pro double“, „zásobník pro string“ atd. (a k tomu vždy řadu funkcí –lišící se jen typem –pro manipulaci se zásobníkem); a kdybych chtěl zásobník pro nový datový typ, tak si tohle vše musím zkopírovat a upravit (úmorné)

Jak může OOP pomoci?

• Posílání zpráv (messagepassing)

–Jednotný způsob, jak přistupovat kobjektům (a tak číst nebo měnit jejich stav)

• Zapouzdření(encapsulation)

–Možnost skrytí datových položek a „pomocných“ funkcí    přehlednější, bezpečnější

• Dědičnost(inheritance)

–Znovupoužitelnost (otestovaného, zdokumentovaného) kódu, a přitom snadná rozšiřitelnost/úpravy

• Polymorfismus(polymorphism)

–Umožňuje např. datové struktury pro libovolné typy

Svět OOP (pojmy)

• Objekt(instance třídy)

• Třída

–Atribut

–Metoda

• Statickámetoda

• Konstruktor, destruktor

Objekt, třída, zpráva

• Obecný (metodický) pohled:

–Entita reálného světa –objekt

–Šablona (vzor) pro objekty –třída

–Způsob komunikace objektů –zprávy

• Techničtější pohled:

–Třída= „lepší“ datový typ

• Definuje datové položky a možné operace s nimi

• Lepší proto, že umožňuje dědičnost (a související principy)

–Objekt= proměnná tohoto typu

–Reakce na zprávu= volání metody


Objekt
(object)

 

 

 

 

 

Objekt (object)

Vlevo je objekt třídy Osoba –jmenuje se Jean Smith(ová), věk 35 let, váha 120 (liber = 55 kg). Má auto, což je další objekt: (vpravo) Objekt třídy Auto –jde o model Ford Escort, SPZ je THX-1138, barva bílá, najeto 64000 mil.

„Slupka“ objektu (obdélníkové bloky okolo dat objektu) znázorňuje zapouzdření –kdatům uvnitř (k„jádru“ objektu) se dá dostat jen spomocí metod, které tvoří tuto „slupku“.

Třída, instance třídy

Třída, instance třídy


 

Vlevo je vzor (šablona) pro auta, tj. třída Auto (classCar). Definuje, jaké datové položky všechna auta budou mít (výrobce, model, SPZ, barva, ujeté míle), a také chování všech aut (metody tvořící „slupku“).

Vpravo jsou dva objekty třídy Auto –liší se hodnotami datových položek. Chování ale budou mít všechna auta stejné (je dáno třídou). Objektům se někdy říká „instance třídy“.

Obrázek třídy připomíná papír, na kterém je nakreslený určitý tvar a jeho rozměry. Tím je znázorněno, že třída je šablonou

(vzorem) pro objekty.

Definice třídy

• Každá třída definuje dvě věci:

–Atributy(attributes) = datové položky charakterizující stavobjektů

• Např. u třídy Auto: výrobce, model, SPZ, barva, …

• Říká se jim také proměnné instance (instance variables), členské proměnné (membervariables), fieldsnebo properties*

–Metody(methods) = funkce (procedury) charakterizující chováníobjektů

• Např. u třídy Auto: nastartuj, rozjeď se, zrychli, zastav, …

• Říká se jim také functionmembers

* Ale pozor, např. v jazyce C# pojem fieldznačí atribut, propertyje něco jako „lepší atribut“(viz závěr prezentace) a

attributesjsou úplně speciální prvky jazyka. Holt každý jazyk používá trochu jinou terminologii Definice třídy (ukázka, C#)

Vytvoření objektu (ukázka)

Situace: máme definovanou třídu Autoa chceme vytvořit nějaký objekt z ní (tj. instanci třídy Auto). Jazyk                                                      Kód                          Poznámka

C++ (objekt)                                         Auto x;                             Automatické vytvoření objektu při deklaraci proměnné


 

C++ (ukazatel na objekt)                   Auto *p;

p = newAuto();

Java, C#                                                 Autox;

x = newAuto();


 

Ruční vytvoření objektu pomocí operátoru new

 

Objekty v Javě/C# se chovajípodobně jako

ukazatele na objekty v C++


 

Posílání zpráv

• Zpráva = požadavek, aby objekt něco vykonal

–Např. provedl akci, vrátil hodnotu, …

–Metoda třídy = obsluha dané zprávy

• Chci-li poslat nějakou zprávu, musím určit:

–Kterému objektu zprávu posílám (příjemce)

–Jakou zprávu posílám (a s jakými parametry)

Posílání zpráv (ukázka)

Situace: máme objekt x(příjemce) z třídy Auto, kterému chceme poslat zprávu Zrychli(s číselným parametrem 10).

Jazyk

Kód

Poznámka

C++, Java, C#

x.Zrychli(10);

Operátor .(tečka), zápisodpovídá klasickému volání

metody

C++(když xje ukazatel)

x->Zrychli(10);

Operátor->(šipka), zápisodpovídá klasickému volání

metody

Objective-C

[x Zrychli:10]

Jiný způsobzápisu, ale význam je stejný (objektu xse

pošle zpráva Zrychlisparametem10)

 

Pozor: Poslat určitou zprávu lze objektu jen tehdy, když autor třídy příslušnou metodu označil jako veřejnou(veřejně použitelnou), viz dále.

Přístup k atributům (ukázka, C#)

Z kódu mimo třídu

Použijeme operátor .(tečka):

Pozor: Přistupovat k atributu objektu lze z kódu mimo třídu jen tehdy, když autor třídy příslušný atribut označil jako

veřejný(veřejně použitelný), viz dále.

Z kódu metody třídy

Jako příjemce zprávy použijeme this:


Nebo jako by šlo o lokální
proměnnou:

 


 

Veřejné a neveřejné položky

• Autor třídy může určit, které položky (datové i funkční, tj. metody) jsou veřejné, a které naopak neveřejné (např. jen pro použití uvnitř třídy jako pomocná proměnná či funkce)

Jazyk                       Veřejnápoložka           Neveřejná položka            Výchozí stav (intx)

C++, C#                 publicintx;                           privateintx;                                 Neveřejná (jen uvnitř třídy)

Java                         publicintx;                           privateintx;                                 Neveřejná(jen uvnitř balíčku*)


 

Objective-C             @public intx; charc;


 

@private intx; charc;


 

Neveřejná (jen uvnitř třídy)


 

 

Statická metoda

• Nyní rozlišujeme třídy a objekty

• Co kdybychom se ale na třídu také dívali jako kdyby to byl jeden (speciální) objekt?

–Pak bychom mohli mluvit o tom, že posíláme zprávu nějaké třídě (voláme metodu třídy)

• Taková metoda samozřejmě nemůže pracovat s hodnotami atributů (číst/měnit), protože třída atributy jen deklaruje,

neukládá si jejich hodnoty

–Jinými slovy taková metoda není závislá na konkrétním objektu

• Taková metoda se označuje jako statická metoda(též metoda třídy, static method, classmethod)

Statická metoda (ukázka, C#)

Metoda LatinskeJmenoje označena jako static, tedy nezávisí na atributech třídy Clovek(jméno, věk, váha, …)


 

 

 

 

Statická proměnná, statická třída

• Statická proměnná (proměnná třídy):


 

 

Statická metoda může používat pouze:

–Statické proměnné

–Statické metody téže třídy

• Příklady statických tříd (C#):

Klikni na název třídy azobrazí se související dokumentace na webu.

Konstruktor (constructor, ctor)

• Speciální metoda třídy, která vytvoří nový objekt (instanci) dané třídy

–Přesněji řečeno alokaci (zabrání) paměti pro atributy a uložení informace o tom, ke které třídě objekt patří (aby se vědělo, které metody lze použít) provede obvykle daný programovací jazyk

–Kód konstruktoru typicky provádí inicializaci objektu

• Nastavuje počáteční hodnoty atributů

• Provádí nějaké počáteční akce, které závisí na typu objektu (např. alokace paměti pro určitou datovou strukturu, otevření určitého souboru, připojení k databázi a výběr určité tabulky atd.)

• Pro jednu třídu může existovat více konstruktorů


–Odliší se parametry (C#, Java, PHP, …) nebo jménem (Perl) Konstruktor s parametry (ukázka, C#)

 

V řadě jazyků se konstruktor pozná tak, že je to metoda, která se jmenuje stejně jako třída (tj. v ukázce Clovek).


 

 

 

Vytvoření objektu (použití příslušného konstruktoru)

Destruktor (destructor, dtor)

• Speciální metoda třídy, která je provedena (těsně) před zánikem objektu

–Umožňuje provést „úklid“ (zavření otevřených souborů, uvolnění přidělené paměti atd.)

• Destruktor v C#:

–Jmenuje se stejně jako třída, ale na začátku názvu má vlnovku: ~Clovek

–Volá se automaticky (nelze explicitně zavolat)

• Lze tedy definovat jen jeden destruktor, a to bez parametrů

Garbagecollection

• Způsob automatické správy paměti

–Garbage(odpadek) = paměť obsazená objekty, které se už dále v programu nepoužívají

–Garbagecollector(sběrač odpadků) = nástroj, který tyto nepoužívané objekty detekuje (zjišťuje) a následně příslušnou paměť uvolňuje


 

• Detekce není úplně triviální, protože objekty můžou navzájem odkazovat na sebe a v případě cyklických odkazů tak může vzniknout falešný dojem, že jsou používány

–První použití: 1959 (jazyk Lisp)

 

Zánik objektu (ukázka)Jazyk       Kód                    Poznámka


 

C++ (objekt)                                         Auto x;

…

(žádnáakce)

C++ (ukazatel na objekt)                   Auto *p;

p = newAuto();

…

deletep;

Java, C#                                                 Autox;

x = newAuto();

…

(žádná akce)


 

Automatické zrušení objektu na konciplatnosti proměnné

 

Ruční zrušeníobjektu pomocíoperátoru delete

 

 

Automatické zrušení objektu, když už se nepoužívá (díky

garbagecollectoru)


 

Zajímavost: property(C#)

• Mám objekt třídy Button(tlačítko v GUI) a ten má atribut Text

–Pro přístup k atributu musím (kvůli zapouzdření) použít příslušné metody:


 

 

–Přitom hezké by bylo moci psát (jako by to byl publicatribut):


 

 

–Toto lze zařídit v jazyce C# pomocí tzv. property

Zajímavost: property(C#)


 

 

 

Propertynení proměnná (nemá vyhrazené místo v paměti), je to spíše sada metod. Tyto metody se zavolají při přístupu k dané property(metoda getpři čtení, metoda setpři zápisu –zapisovaná hodnota je uložena ve speciální proměnné value).

Pokud je tělo daných metod triviální (jako v ukázce výše), lze použít i zkrácený zápis (vlevo). Místo pro uložení hodnoty si C# vytvoří automaticky sám.

OOP: dědičnost

Dědičnost (inheritance)

• Výhoda: znovupoužitelnost

–Využít už existující kód (třídy)

• Popsat jen změny:

–Přidat

–Změnit (přepsat)

–Odebrat* Jednoduchá dědičnost

Jednoduchá dědičnost

Předci jsou obecnější, potomci jsou konkrétnější: Osoba je konkrétnější typ Objektu, Doktor je konkrétnější typ Osoby, Psychiatr je konkrétnější typ Doktora.

Zde zobrazená dědičnost je jednoduchá vtom smyslu, že každá třída má nejvýše jednoho předka.

Třída Object(Objekt) je předkem všech ostatních tříd. Třída Person(Osoba) přidává tři nové atributy: jméno (name), věk (age) a váhu (weight). Třída Doctor(Doktor) je potomek třídy Person: dědí všechny tři atributy od třídy Persona navíc přidává dva nové: škola (medSchool) a číslo licence (licenseNo). Jiný potomek třídy Personje Typist(Písař), který přidává jen jeden atribut: počet slov za minutu (wpm). Třída Psychiatrist(Psychiatr) je potomkem třídy Doctor.


 

Jednoduchá dědičnost

Jednoduchá dědičnost

Instance (objekt) třídy Doctormá všechny atributy definované u třídy Doctor(school, license) i u všech jejích předků, tj. zde atributy třídy Person(name, age, weight) i třídy Object(bez atributů).

Totéž platí i pro metody: u objektu třídy Doctorlze používat metody definované u třídy Doctori u všech jejích předků, tj. zde

metody setWeight, getWeighta examine(na obrázku to však znázorněno není)

Vícenásobná dědičnost

Vícenásobná dědičnost

Instance (objekt) třídy NavyDoctormá všechny atributy definované všemi svými předky, tj. name, age, weight(od třídy

Person), school, license(od třídy Doctor) i ranka ship(od třídy NavyOfficer)

Třída NavyOfficer(Námořní důstojník) je potomkem třídy Persona definuje dva nové atributy, rank(hodnost) a ship(loď), a dvě nové metody, hoistTheMainsail(Napnout hlavní plachtu) a swabTheDeck(vytřít palubu).

Třída NavyDoctor(Doktor námořník) je potomkem jak třídy Doctor, tak třídy NavyOfficer, zdědí tedy atributy a metody obou tříd.

Vytvoření objektu (ukázka)

Situace: Chci vytvořit třídu Doctor, která je potomkem třídy Person.

Jazyk

C++, C#

Kód

classDoctor: Person

{

// popis změn

}

Poznámka

Java

classDoctorextendsPerson

{

// popis změn

}

 

C++

class NavyDoctor: Doctor, NavyOfficer

{

// popis změn

}

C++ umí vícenásobnou dědičnost

 

Přiřazení potomek ↔ předek Osoba o = newOsoba(); Doktord = new Doktor();

// Doktorje pomotekodOsoba Osobao2 = d; // lzeprovést? Doktord2 = o; // lzeprovést?

Jinými slovy: Lze se k Doktorovi chovat tak, jako by byl Osobou? Jinými slovy: Lze se k Osobě chovat tak, jako by byla Doktorem? Přiřazení potomek předek

Doktor

Jméno                                                                                            Osoba

Věk                                                                                                Jméno


 

Váha                                                                                              Věk

ČísloOsvědčení                                                                                 Váha

řekniVáhu()                                                                                     ČísloOsvědčení

nastavVáhu()                                                                                   řekniVáhu()

vyšetřiPacienta()                                                                              nastavVáhu()

vyšetřiPacienta()

 

Přiřazení potomka (Doktor) do předka (Osoba) je vždy bez problémů, jednoduše se některé informace „zapomenou“. Ostatně každý Doktor je díky dědičnosti Osobou (umí vše co Osoba), takže s ním lze jednat jako s Osobou.

Předek    potomek

Osoba                                                                Doktor

Jméno                                                 Jméno

Věk                                                    Věk

Váha                                                   Váha

řekniVáhu()                                          ČísloOsvědčení???

nastavVáhu()                                       řekniVáhu()

nastavVáhu()

vyšetřiPacienta() ???

 

Přiřazení předka (Osoba) do potomka (Doktor) je obecně problematické, protože předek nemusí umět vše, co se od potomka žádá. Kdybych se Osoby, která má být považována za Doktora, zeptal na číslo osvědčení, co mi má odpovědět? Žádný takový atribut nemá. Kdybych ji požádal o vyšetření pacienta, co má udělat? Žádnou takovou metodu nemá.

Přiřazení potomek ↔ předek

Osobao2 = d;

Lze vždy provést (nejen při přiřazování, ale i v rámci předávání parametrů metodám atd.)

Doktord2 = o;

Problematické, takže v jazyce C# implicitně provést nelze. Programátor ale může konverzi vynutit explicitním zápisem:

Doktord2 = (Doktor)o;

Proměnná ose přetypuje (zkonvertuje, anglicky cast) na třídu Doktora teprve pak je přiřazena do proměnné d2. Odpovědnost za logickou správnost konverze je na programátorovi (a hlavně je přímo v kódu vidět, že k takové konverzi dochází.

Dědění: zvláštnosti

• Obvykle je dědění možnost, jak něco udělat

–Můžou ale existovat situace, kdy programátor potřebuje dědění

vynutit, nebo naopak zakázat

• Zákaz dědění od nějaké třídy:

–Modifikátor třídy: final(Java), sealed(C#)

• Vynucení dědění:

–Tzv. abstraktní třídy

Abstraktní metody/třídy

• Abstraktní metoda:

–Před deklaraci metody se napíše abstract(C#, Java)

–Není definováno tělo metody

• Aby bylo možné danou metodu někdy zavolat, je třeba definovat její tělo v některém potomkovi dané třídy

• Abstraktní třída:

–Před deklaraci metody se napíše abstract(C#, Java)

• Má-li třída alespoň jednu abstraktní metodu, pak musí být sama označena jako abstrakt

–Nelze vytvářet instance třídy(!)

•

 

 

 


Třída slouží jen k tomu, aby se od ní dalo dědit –aby sloužila jako předek nějakých dalších tříd (viz dále polymorfismus: pozdní vazba)
Abstraktní metody/třídy

 

Třídy s názvem kurzívou jsou abstraktní třídy: Shape(Tvar), Polygon(Mnohoúhelník). Třídy s tučným názvem označují konkrétní (ne- abstraktní) třídy: RegularPolygon (Pravidelný mnohoúhelník), IrregularPolygon (Nepravidelný mnohoúhelník), Rect(Obdélník), RoundRect(Obdélník s kulatými rohy), Circle(Kruh).

Od abstraktních tříd zde nemá ani smysl vytvářet instance, protože tyto třídy neobsahují informace (atributy) potřebné pro vykreslení příslušného geometrického tvaru. Konkrétní třídy už tyto informace


 

obsahují, např. Circlemá center(střed) a radius(poloměr), takže daný kruh by vykreslit šel. Abstraktní třídy tedy zde fungují jen jako pomůcka –společný předek určité skupiny tříd.

Dědičnost

Výhody                                                  Nevýhody

Znovupoužitelnostkódu                              Vyžaduje OOP


 

Změny bez zásahůdo původního funkčního a otestovaného kódu

Podporuje tvoru rozšířením či upřesněním již existujícího, nekompletním předěláním Možné snížení výkonu (trochu)**


 

Dědění vlastností,které nejsou žádoucí

Obtížné ladění programu přivětším množství tříd*


 

 

Zapouzdření (encapsulation)

• Závislostcizího kódu na konkrétní implementaci mého modulu (mé třídy)    problémy

–Změním implementaci (vylepšení, oprava chyby)    cizí kód může přestat fungovat

–Cizí kód mi může „rozbořit“ datové struktury

–Jen doporučení (např. v dokumentaci) nestačí

–Je nutné omezit/řídit možnosti přístupu

• Přístupnost (C#):

–private= jen třída (jen metody dané třídy)

–protected= jen třída a potomci

–public= veřejné (kdokoli)

Zapouzdření (příklad)

• Osoba.Zisk():

 

return příjmy –výdaje;

• Osoba.Zisk():

 

return příjmy –výdaje+ úspory * úrokováMíra–daně(příjmy, odpočitatelné položky); Lze změnit implementaci metody, navenek se nepozná

Zapouzdření

Výhody                                                              Nevýhody


 

Uživatel serychle naučí s třídou pracovat (nemusí se zabývat detaily)


 

Znovupoužitelné třídy je třeba opatrně naplánovat (zejménaveřejná rozhraní)


 

Uživatel nemusí mít strach,že něco pokazí                Přístup přes metody může být (trochu)

pomalejšínež přímý přístup

Tvůrce může změnit implementaci, ale navenek se

nic nezmění –vše funguje

Polymorfismus

• „Vícetvarost“

• Týká se třech oblastí:

–Dle parametrů

• Tzv. šablony (templates) –nechme nyní stranou

–Přetěžování (overloading) metod / operátorů

• Pod jedním názvem je více metod / operátorů (rozlišují se typem parametrů)

–Pozdní vazba

• Jedna proměnná může obsahovat více různých typů objektů (ale jen potomci) Přetěžování metod (příklad)


 

 

 

 

 

 

 

 

 

Přetěžování operátorů (příklad)

// Matice M krát vektor x je vektor y

y = M * x;


 

// Matice M krát číslo 2 je matice N N = M * 2;

// Číslo 4 krát vektor x je vektor y

y = 4 * x;

V principu je to totéž jako přetěžování metod, protože výše uvedené příklady jdou přepsat jako: y = operátor_krát(M, x);

N = operátor_krát(M, 2); y = operátor_krát(4, x);

Přetěžování metod a operátorů

Výhody                                                                 Nevýhody

Jednodušší (pro uživatele)rozhraní tříd a knihoven         Přivýběru názvů metod a parametrů musí být tvůrce

opatrný


 

Přehlednějšíkód při používání takových metod a operátorů

Časná a pozdní vazba

• Týká se volání metod třídy

• Časná vazba(static binding, early binding)


 

Jsou-li názvy zvoleny špatně, může být uživatel zmaten


 

–Typ objektu je určenuž při kompilaci (podle typu příslušné proměnné)

• Pozdní vazba(latebinding, dynamic binding, dynamic dispatch)

–Typ objektu je určen až při běhu programu (objekty si svůj typ „pamatují“)

• Proměnná je oficiálně typu (třídy) XYZ

• Do ní lze přiřadit i jakéhokoli potomka třídy XYZ (přiřazení potomek    předek je vždy v pořádku)

• Až při běhu programu se zjistí, která třída je v dané proměnná skutečně uložena a zavolá se příslušná metoda (tj. metoda

potomka XYZ, ne metoda XYZ)

Časná a pozdní vazba(příklad)

• Chci mít datovou strukturu (např. pole), ve které budou prvky různého typu. S těmito prvky chci provádět nějakou operaci (např. print). Jak to provést?

• Řešení bez využití dědičnosti (časná vazba):

–Každý prvek si bude pamatovat svůj typ (ve vhodné datové položce)

–Pro každý typ vytvořím „konverzní“ funkci, která prvek převede na daný typ

–U každého typu udělám funkci (metodu) print

–Při procházení pole nejprve z datové položky zjistím, jakého typu položka je, pak ji konverzní funkcí formálně převedu na daný typ a nakonec zavolám print

Časná vazba

For(inti = 0; i < pole.velikost; i++)

{

Objectprvek= pole[i];

if (prvek.typ == INT_OBJECT) PrevedNaINT_OBJ(prvek).print();

else if (prvek.typ == STRING_OBJECT) PrevedNaSTRING_OBJ(prvek).print(); else if (prvek.typ == CIRCLE_OBJECT) PrevedNaCIRCLE_OBJ(prvek).print(); else if (…)

PrevedNa…

}

Nevýhody tohoto řešení:

1) Pracné, složité, nepřehledné

2) Při přidání nového typu musím změnit i veškerý kód, který by daný typ používal (musím přidat nový if). Ale ten kód nemusí být můj kód…

Pozdní vazba

Při použití pozdní vazby stačí mít společného předka (např. třídu Object) a na něm mít deklarovanou metodu print()(klidně bez těla, tj. abstraktní). U potomků (u tříd Int_Obj, String_Obj, Circle_Obj, …) tělo metody print()definuji.

For(inti = 0; i < pole.velikost; i++)

{

Objectprvek = pole[i]; prvek.print();

}

Použije se vždy taková metoda print(), která odpovídá danému typu (dané třídě, která musí být potomek třídy Objekt). Navíc při přidání nového typu stačí u dané třídy nadefinovat tělo metody print()a nic dalšího (ani výše uvedený kód) neměním.

Pozdní vazba (ukázka)

Situace: Chci zařídit, aby se metoda print()volala pomocí pozdní vazby.

Jazyk       Kód                             Poznámka


 

C#             classObject{ virtualpublic print();

}

classInt_Obj{ overridepublic print();

}

C++          classObject{ virtualpublic print();

}

classInt_Obj{ public print();


 

Daná metoda se pak označuje jako „virtuální“.

 

 

 

 

Daná metoda se pak označuje jako „virtuální“.


 

}

 

 


 

Java          classObject{ public print();

}

classInt_Obj{ public print();

}

 

Výhody OOP


 

U metodje pozdní vazba výchozíchování (není třeba přidávat žádný modifikátor).


 

Minimalizace opakování kódu (dědičnost) –Není nutné psát, testovat, spravovat

• Skrytí implementačních detailů (zapouzdření) –Bezpečnější, jednodušší na pochopení

• Uživatel třídy si nemusí tolik pamatovat (polymorfismus)

• Není nutné přepisovat kód jen proto, že někdo přidá nový typ (pozdní vazba)

Snazší vytvořit a používat (znovupoužitelné) SW komponenty

OOP: návrh

ANALÝZA A NÁVRH

Dědičnost, nebo asociace?

• Vztah „je“ („is“)   dědičnost tříd

–Např. „Doktor je Osoba“ (je osobou –má všechny její vlastnosti)

• Vztah „má části“, „obsahuje“ („has“) nebo „komunikuje s“    asociace tříd

–Např. „Telefon má Reproduktor a Mikrofon“ (má části, skládá se z)

–Jak zachytit (implementovat) asociaci, to si ukážeme dále

Kdo implementuje asociaci?

(mezi dvěma třídami)

• Obě třídy

–Vhodné v situaci, kdy třídy navzájem intenzivně komunikují (tj. musí vědět jedna o druhé a navzájem si volají metody)

• Jedna třída

–Vhodné pro agregaci/kompozici (jedna třída je částí druhé)

• Ani jedna z nich

–Vhodné pro situaci, kdy je asociace složitá –realizaci asociace zastane samostatná (třetí) třída

Implementace asociace: obě třídy

Např. Zaměstnanec (Employee) a Manažer (Manager) –oba musí komunikovat navzájem (manažer posílá úkoly zaměstnanci, zaměstnanec se ale také často obrací na svého manažera). Realizace: třída Employeemá atribut manager(kdo je jeho manažerem), třída Managermá jako atribut underlings(podřízení). Tedy existence vztahu je vidět v obou třídách (v obou třídách je nový atribut).

Implementace asociace: jedna tříd classŠkola {

stringnázev;

Katedra[] katedry;

// další položky

}

classKatedra { stringnázev; Osoba vedoucí;

// další položky

}

Např. škola a její katedry (katedra informatiky, katedra jazyků, katedra práva atd.). Vztah lze jednoduše implementovat jako nový atribut ve třídě Škola –seznam kateder. Ve třídě Katedra se nic měnit nemusí.

Implementace asociace: ani jedna

Např. vztah „sdílí kancelář“ (zaměstnanci). To by šlo udělat tak, že by každý zaměstnanec měl seznam kolegů, kteří sním sdílí kancelář, ale tyto seznamy by se pracně musely udržovat a synchronizovat. Jednodušší je vytvořit novou třídu Kancelář (Office) a ta by u sebe měla (jako atribut) seznam obyvatel (occupants). Tato třída tedy zachycuje (implementuje) daný vztah. V ukázce je ještě pohodlnější varianta –i zaměstnanec má informaci o tom, v jaké je kanceláři (atribut office).

Agregace vs. kompozice

• Někdy se rozlišuje míra těsnosti vztahu tříd, kde jedna obsahuje druhou


 

–Když zanikne „celek“, zaniknou i „části“?

• Kompozice (těsnější vztah):

–Např. vztah Škola –Katedry (vše myšleno jen jako organizační jednotky)

• Zanikne-li Škola, pak zaniknou i Katedry (Katedra nemůže samostatně existovat)

• Agregace (volnější vztah):

–Např. vztah Katedra –Vyučující

• Zanikne-li Katedra, Vyučující žijí dál (samostatně existují)

Abstrakce

• Úkol abstrakce: reálný svět    třídy

–Listy (v hierarchii dědičnosti) jsou obvykle snadné, protože ty odpovídají typům objektů z reálného světa

–Problém bývá vymyslet dobře tu hierarchii

• Vznikají tak další, pomocné třídy

–A také je třeba vymyslet, které atributy a metody budou u kterých tříd

Abstrakce: obecný postup

1. Mám nějaké třídy

2. Najít společné atributy nebo chování dvou nebo více tříd

3. Tyto společné věci vyčlenit do nové (pomocné) třídy

4. Ostatní zmíněné třídy od této nové třídy budou dědit (a definují jen odlišnosti)

Postup lze opakovat

Abstrakce (přístupy)

• Přístupy k abstrakci:

–Dle funkce (tj. dle metod tříd)

–Dle struktury (tj. dle atributů tříd)

–Dle obojího

–Minimální návrh

• Příklad:

–Rovinný obrazec (Shape), Čtverec (Square), Obdélník (Rectangle)

•


Potřebuji znát umístění a rozměry obrazce a mít metodu pro počítání plochy (area)
obrazce Abstrakce dle funkce

 

 

 

• Zaměření na funkce (metody objektů)

• Lze napsat metodu area()tak, aby se dala použít u obou tříd?

–Tj. byla jen jedna metoda?

–Ano

–Čtverec je pak jen speciální případ Obdélníku

Čtverec ale zdědí 4 atributy, stačily by mu přitom jen 3 (top, left, side)

Abstrakce dle struktury

Zaměření na efektivní uložení dat (strukturu)

• Čtverci stačí tři atributy, obdélník si přidá čtvrtý

–Datově lépe už to nejde

–Obdélník je zde „obohacením“ (rozšířením) čtverce

Ne moc logické, hierarchie se navíc odvozuje od interních detailů (datových struktur), tj. při změně implementace objektů bude hierarchie špatně.

Abstrakce dle obojího

Hledáme, co mají třídy společného (obecně)

–Čtverec i obdélník mají společný obecný vzorec:obsah = šířka ∙ výška


 

–Ale datové struktury mají jiné    dát je až do potomků

• Předek konkrétní hodnoty získá metodami

Náročné navrhnout, mnoho abstraktních tříd může znamenat pomalost a nepřehlednost


Minimální
návrh

 

 

Minimalizovat počet úrovní a také počet tříd

–Jeden společný předek se hodí (polymorfismus) Nevyužije v plné šíři výhod dědičnosti, ne moc logické Plusy a minusy

Dle                                          Plusy                                                                                  Minusy


 

Funkce                                   Odpovídá reálnému světu, funkční soudržnost,

snadno rozšiřitelné


 

Strukturanení optimální (zbytečná duplikace)


 

Struktura                               Efektivní uloženídat                                           Neintuitivní, závislost na implementaci, nepřizpůsobitelné

Obojí                             Intuitivnía datově efektivní                                 Náročnéna návrh, může klesnout výkon (hodně abstraktních tříd)

Minimální počet úrovní      Méně tříd –přehlednější, jednodušší debugging       Nezachová vztahyreálného světa, nevyužije plně

dědičnosti (redundance kódu)

Abstrakce: který přístup zvolit?

• Záleží na prioritách(co je hlavní):

–Přehlednost, intuitivnost     dle funkce

–Efektivita uložení dat    dle struktury

• Při velkých datových objemech nebo při velkém množství objektů daného typu

–Obě předchozí kritéria    kombinace

–Jednoduchost, výkon    minimální návrh

KVALITA NÁVRHU –PROPOJENÍ A SOUDRŽNOST

Silné propojení tříd(strong/high/tightcoupling)

• O silné propojení jde, když:

–Je vzájemná závislost na vnitřních strukturách

–Třídy si posílají mnoho různých zpráv nebo jsou zprávy „složité“ (záleží na pořadí nebo mají hodně parametrů)

• Silné propojení vadí,protože brání změnám

–Nelze změnit jednu třídu,protože to „rozbije“ tudruhou (třídy se navzájem„drží pod krkem“)

 

 

 

Zmenšení propojení: zprávy

Je to silné propojení? Ano: je zde hodně různých zpráv, záleží na pořadí.

Proč je to špatně? Třídu Autokvůli tomu nelze změnit, např. těžko by se dělalo auto s automatickou převodovkou (bez spojky

atd.).

Jak to udělat lépe? Třída Autoať má jedinou metodu nastartuj(klíč)a ať si sama interně zařídí to nastartování. Zmenšení propojení: struktura


 

 

 

Je to silné propojení? Ano: třída Doktor šahá na vnitřní strukturu (jméno, příjmení) jiné třídy (Osoba).

Proč je to špatně? Třídu Osobakvůli tomu nelze změnit, např. těžko by se dělala osoba s prostředním jménem (např. „William Henry Gates“).

Jak to udělat lépe? Doktor by měl využít metodu getJmenosvého předka, tj. return "MUDr. " + base.getJmeno();

Pravidlo nezávislosti(LawofDemeter)

Pravidlo, které předchází závislosti na struktuře cizích tříd

• Říká: třída by měla znát (a využívat) jen své „přímé okolí“, nikoli vzdálenější třídy

Alternativní znění: při volání metody je povolena jen „jedna tečka“. Tedy volání x.metoda()je povoleno, ale x.y.metoda()už nikoli, protože to už vyžaduje znalost vnitřní struktury objektu x(že má nějakou položku y).

Příklad: viz cvičení (Psí nohy a Zákazník a peněženka).

Pravidlo nezávislosti(LawofDemeter)

• Technická definice pravidla:

–Když mám objekt X s metodou M, tak metoda M může volat pouze metody následujících objektů:

• X (objektu samotného, tj. this)


 

• Přímá součást X (atribut)

• Parametr metody M

• Lokální proměnná (objekt vzniklý uvnitř metody M)

• Globální proměnná

Např. pokud jako parametr dostanu objekt třídy Škola, neměl bych volat metodu Škola.katedra[INF].setVedoucí("Trčka"), protože tím nevolám metodu parametru (školy), ale jeho součásti. Měl bych volat pouze některou z metod školy jako celku, protože jinak budu závislý na vnitřní struktuře školy (že má katedry atd.).

Soudržnost (cohesion)

• Jak dobře atributy a metody třídy odpovídají dané myšlence (konceptu)

• Hodnotí se:

–Relevance (relevance)

–Potřebnost (necessity)

–Úplnost (completeness)

Relevance

• Souvisí prvek s třídou přímo?


–Nebo prvek s třídou souvisí prostřednictvím „neviditelné“ jiné
třídy?

 

 

Atributy značkaAutaa rokVýrobyAutaje lepší dát do samostatného objektu (Auto). Už jen proto, že osoba nemusí mít auto, nebo že může mít aut více. Pro porušení relevance je typické, že název atributu/metody obsahuje jméno jiného objektu (znackaAuta, rokVyrobyAuta).

Potřebnost

• Je prvek nezbytně nutný?


 

 

Potřebujeme u zraněného pacienta znát oblíbenou TV show? To leda tak u pacienta, který už je v rekonvalescenci…

Úplnost

• Pokrývá vše potřebné?


 

 

U zásobníku by kromě metody push(přidej prvek na zásobník) měla být určitě metoda pop(vrať/odeber prvek zvrcholu zásobníku).

Silná soudržnost

• Snažíme se o silnou funkční soudržnost…

–Každá metoda je relevantní, nezbytně nutná a dohromady metody pokrývají vše potřebné

• … i o silnou strukturální soudržnost

–Každý atribut je relevantní, nezbytně nutný a dohromady atributy pokrývají vše potřebné

Funkcionální programování Funkcionální paradigma

• Patří mezi deklarativní paradigmata

–Důraz: coprogram počítá (vztah vstup–výstup)

–Ne tak důležité: jakprogram počítá (akce)

• Styl: práce s funkcemia jejich aplikace na argumenty

Srovnání paradigmat

• Imperativní

–Program = příkaz

–Výpočet = posloupnost akcí (stav    stav)

–Výsledek = účinek těchto akcí

–Jazyky: C, C++, C#, Java, Python, PHP, …

• Funkcionální

–Program = výraz

–Výpočet = úprava (zjednodušování) výrazu

–Výsledek = hodnota (dále nezjednodušitelný tvar výrazu)

–Jazyky: Lisp(1958*), Scheme(1975), Erlang(1986), Haskell(1990), Scala(2003), F# (2005), Clojure(2007), …

Příklady použití funkcionálních jazyků

• Akademická sféra

• Komerční sféra:

–Jazyk Erlang(Ericson) –systémy odolné proti selhání (telekomunikace)

–Jazyk Scheme–simulace

–Jazyk OCaml–finanční analýza, verifikace ovladačů zařízení, programování průmyslových robotů

–Jazyk Haskell–letectví a kosmonautika, návrh hardware

Funkcionální koncepty mají podporu i v původně imperativních jazycích Rok/měsíc     Jazyk              Poznámka

1997                   JavaScript       Některé koncepty až později(např. 2008: closures)


 

2007/11

C# 3.0

Pěknýpřehledový článek:

 

 

POPOVIC, Jovan. Functionalprogrammingin C#. CodeProject[online]. 2012-06-10 [cit. 2014-04-

 

 

25]. Dostupné na WWW: http://www.codeproject.com/Articles/375166/Functional-

 

 

programming-in-Csharp

2009/06

PHP 5.3

 

2011/08

C++11

 

2014/03

Java 8

Některé koncepty už v Javě 7 (např. closures)

Co jsou to closures(a další koncepty), to si samozřejmě ukážeme dále Zajímavé články

• Zajímavé články (anglicky), které přinášejí argumenty, proč „klasické“ imperativní (příkazové) programování nestačí (vždy):

–CARMACK, John. FunctionalProgrammingin C++. #AltDevBlog[online]. 2012-04-26 [cit. 2014-04-29].Dostupné na WWW:

http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/

•„No matter what language you work in, programming in a functional style provides benefits. You should do it whenever it is

convenient, and you should think hard about the decision when it isn’t convenient.“

–MILEWSKI, Bartosz. The Downfall of Imperative Programming. FP Complete[online]. 2012-04-09 [cit. 2014-04-29].Dostupné na WWW: https://www.fpcomplete.com/blog/2012/04/the-downfall-of-imperative-programming

•„If you think you can stay away from functional programming, you're mistaken.“

John Carmacje programátor, jeden ze zakladatelů id Software (vytvořili počítačové hry Wolfenstein3D, Doomnebo Quake). BartoszMilewskinapsal knihu o C++ a pomáhal při návrhu programovacího jazyka D.

Rysy současných funkcionálních jazyků

• Deklarativnost

–Vyšší úroveň jazyka    zápis je bližší specifikaci, krátký zápis (bez nepodstatných implementačních detailů), čitelný zápis

• Ortogonalita

–Se všemi hodnotami se pracuje stejným způsobem   jednoduchá syntaxe i sémantika, velká expresivita (šíře myšlenek, které lze jazykem popsat)

• Bohatý typový systém, silná typová kontrola

–Rychlá detekce chyb, snadné ladění Referenční transparentnost

–Stejný výraz má vždy stejný výsledek (nezávisí na stavu programu, nemá vedlejší efekty)

• Proměnné nemění svou hodnotu (jen jedno přiřazení)

–Z ní vyplývající možnosti formální manipulace sprogramy, zejména:

• Dokazování správnosti

• Paralelizace výpočtů (bez strachu z chyb typu racecondition)

• Optimalizace kódu

–Výraz/funkce/jazyk s touto vlastností se označuje jako „pure“ (čistý)

Haskell

• Budeme si vše ukazovat na jazyku Haskell

–Patří mezi „čisté“ (pure) funkcionální jazyky

–Má jednodušší syntaxi než C#/Java/atd.    na naučení se principů funkcionálního programování je vhodnější

• Zajímavé webové stránky:

–http://tryhaskell.org/

• Interaktivní výuka základů jazyka (anglicky)

–http://naucte-se.haskell.cz/

• Příručka pro začátečníky (česky)

–http://www.fi.muni.cz/~xukrop/ib015/

• Přehledný seznam zdrojů (slovensky Příklady programů


 

 


 

 

 

 

 

 


 

First-classcitizen

• Funkce mají ve funkcionálních jazycích silnou pozici –říká se, že funkce jsou v daném jazyce first-classcitizen(„občan první třídy/úrovně“)

–Tedy že s funkcemi lze provádět stejné operace jako sjinými datovými typy, například:

• Lze přiřadit funkci do proměnné

• Lze předat funkci jako parametr (do jiné funkce)

• Lze použít funkci jako návratovou hodnotu (z jiné funkce).

Funkce vyššího řádu

• Funkce vyššího řádu (highorderfunction) = funkce, která má jako parametr funkci nebo která vrací funkci

• Příklady typických funkcí vyššího řádu:

 

map                                                                         Aplikuje danou funkci (parametr) na každý prvek seznamu

filter                                                                         Použije danou funkci(parametr) jako kritérium výběru prvků ze

seznamu

fold                                                                          „Sbalí“ (agreguje) prvky seznamu pomocí dané funkce (parametr)

 

Funkce vyššího řádu (příklady)

Anonymní funkce

• Anonymní funkce (lambda function) = funkce, která má definované tělo a která je volaná, ale která nemá určené jméno (identifikátor)

–Např. funkce (\x -> x * x)je anonymní funkce

–Dokonce i (+1), (*3), (==20)jsou anonymní funkce, jak uvidíme dále (viz currying)

Currying

• Curryingje technika, kdy je funkce s více parametry převedena na „řetězové“ volání více funkcí, které mají jen jeden

parametr

–Hovoří se o tzv. částečné aplikaci funkce (partialfunctionapplication) nebo také o „zafixování“ některých parametrů funkce

• Jazyk Haskellpoužívá currying


 


 

 


 

 

 

 

 

 

 

 

 

 

 

 

Currying(závěr)

• Všimněme si, že díky curryingujsou všechny funkce „svíce parametry“ vHaskelluautomaticky funkcemi vyššího řádu (protože mají formálně jen jeden parametr a tedy musí vracet funkci)

–Funkce +(plus) má jeden parametr (x) a vracífunkci(která svůj parametr zvětší o x)

–Funkce mapmá jeden parametr (funkci f) a vracífunkci(která seznam převede na jiný seznam aplikací funkce fna jednotlivé

prvky seznamu)

• Funkce map je tedy funkce „zobecni na seznam“, protože z funkce typu např. „číslo    číslo“ udělá funkci typu „seznam čísel

 

 


 

 

Lexikální uzávěr

• Lexikální uzávěr(closure) = funkce společně s „prostředím“, ve kterém je tato funkce odkazovaná (definovaná)

•U definice soucet= \x -> (\y -> y + x)je funkce (\y -> y + x)lexikálním uzávěrem, protože tato (anonymní) funkce potřebuje vědět hodnotu x, která je ale definována mimo funkci –v tzv. prostředí (environment) této funkce

–Prostředím je zde myšlena funkce soucet(a xje v tomto prostředí definována jako parametr funkce soucet)

–Pro svou funkčnost (aby mohla vrátit správnou hodnotu) potřebuje funkce (\y -> y + x)vědět (zapamatovat si, uložit si), v jakém prostředí byla definována (odkázána), která proměnná je tím x, které sama pro výpočet potřebuje (např. uloží si adresu proměnné x)

–Lexikální uzávěr si tedy lze představit jako funkci s „neviditelnými“ parametry (zde je tím neviditelným parametrem proměnná x)

Funkcionální programování2

Líné vyhodnocování

• Líné vyhodnocování(lazyevaluation) je taková strategie při vyhodnocování výrazů, kdy výraz je vyhodnocen až v okamžiku, kdy je vyžádána jeho hodnota

• Příklad (jazyk C#):


 

 

U jazyka Haskellpodobný příklad použít nelze, protože Haskellumí dělit nulou (výsledkem je kladné konečno, které se vypíše

jako 1.#INF)


 

Výraz (x != 0)je vyhodnocen jako falsea protože výraz (false&& cokoliv)je vždy false(nezávisle na hodnotě výrazu cokoliv), tak se výraz ((1 / x) == 0)vůbec nevyhodnocuje a tedy nedojde k chybě dělení nulou při vyhodnocení podvýrazu (1 / x). Nekonečné datové struktury

• Jazyk Haskellpoužívá líné vyhodnocování

• Díky tomu lze pracovat i s (potenciálně) nekonečnými datovými strukturami

–Pokud stačí k vyhodnocení výrazu znát konečný počet prvků takové struktury, pak k žádnému nekonečnému zacyklení (při průchodu strukturou) nedojde

Nekonečné datové struktury (příklad)

• Nekonečnou strukturu lze zapsat třeba takto:

Vstup: [1..]

Výstup: [1,2,3,4,5,6,7,8,9,10,11,…

Funkce „výpis na obrazovku“ potřebuje postupně všechny prvky seznamu, takže výpis pokračuje jedno číslo za druhým až do doby, kdy dojde paměť nebo kdy uživatel ručně přeruší běh programu.

Máme-li ale definovanou funkci prvek, která vrací n-týprvek seznamu (viz cvičení), tak následující program bez problému skončí (chceme vypsat 5. prvek nekonečné struktury):

Vstup: prvek5[1..]

Výstup: 5

Funkce prvek„donutí“ jazyk Haskell, aby postupně zjistil prvních 5 prvků seznamu[1..], další prvky seznamu ale pro získání výsledku nutné nejsou, a tak se díky línému vyhodnocování ani nezjišťují.

Typový systém


Datový typ výrazu můžeme zjistit pomocí příkazu :t
výraz

 

 

Výrazem může být samozřejmě i funkce (funkce &&je logické AND):


Typový systém:
funkce

 

Zápis tvaru X -> Yznamená datový typ „funkce, která ztypu X(parametr) udělá typ Y(výsledek)“

• Zápisy s ->(šipkou) se závorkují zprava, tedy zápisBool-> Bool-> Boolve skutečnosti znamenáBool-> (Bool-> Bool)

–Tedy jde o funkci, která má parametr typu Boola vrací funkci (typu Bool-> Bool)

–Jde o další ukázku toho, že funkce v Haskellumají jen jeden parametr (a že funkce může vracet funkci)

• V jazycích, kde funkce mají více parametrů (např. C#), bychom to četli tak, že je to funkce, která má dva parametry Boola

vrací Bool


Typová třída
(typeclass)

 

Numa(před =>) znamená, že datový typ aje z typové třídy Num

–Do typové třídy Numpatří datové typy Int, Float, Doublea řada dalších* číselných typů

–Funkce +(plus) tedy umí pracovat s různými číselnými typy

• Připomeňme, že zápis a -> a -> a znamená, že funkce +(plus) má parametr typu aavrací funkci (typu a -> a)

•


Existují i další typové třídy (např. Ord,
seřaditelnétypy):

 

Odvození typu (type inference)

Zatím jsme se bez určování datových typů obešli, protože Haskellsi je odvodí sám:

--n-ty prvek seznamu (prvni = 1) prvek 1 (x:xs) = x


prvek n (x:xs) = prvek (n-1)
xs

 

V definici funkce prvekHaskellvidí, že s prvním parametrem funkce děláme operaci (n-1), tedy že patří do typové třídy Num(to

vyplývá zdatového typu funkce -(minus)).

Druhý parametr má tvar (x:xs), tedy jde o seznam (výsledkem funkce :(dvojtečka) je seznam). Výsledkem funkce prvekje x,

což je prvek seznamu. Datový typ prvků seznamu může být libovolný, nemusí jít o typ a(proto je označen jako b).

Typová signatura (type signature)

Pomocí tzv. typové signatury si můžeme datový typ funkce určit (upřesnit) sami:

--n-ty prvek seznamu (prvni = 1)

prvek :: Int -> [b] ->b       ß Typová signatura

prvek 1 (x:xs) = x

prvek n (x:xs) = prvek (n-1) xs

Typovou signaturou funkce jsme datový typ jejího prvního parametru omezili na Int(celé číslo), čímž jsme zakázali funkci volat s parametrem typu např. Floatnebo Double(což by stejně nedávalo smysl a jen by to vedlo kproblémům – neočekávanému chování funkce).

Typový systém podrobněji

• Podrobnější vysvětlení typového systému je například zde:

–Wikibookscontributors. Haskell/Type basics. Wikibooks, The Free Textbook Project[online].2014-05-09, 02:27 UTC [cit. 2014-05-18]. http://en.wikibooks.org/w/index.php?title=Haskell/Type_basics&oldid=2650061

–Wikibookscontributors. Haskell/Type basicsII. Wikibooks, The Free Textbook Project[online].2014-04-24, 08:16 UTC [cit. 2014-05-18]. http://en.wikibooks.org/w/index.php?title=Haskell/Type_basics_II&oldid=2637640


 

Silné stránky funkcionálních jazyků

• Jednoduchost, čitelnost

–Blízké uvažování člověka (zadání)

–Silné prostředky pro abstrakci

• Funkce vyššího řádu

• Velká znovupoužitelnostkódu

–Parametrický polymorfismus

–Líné vyhodnocování

• Stabilita programů

–Silná typová kontrola

–Referenční transparentnost

• Jednodušší formální verifikace programu

Slabiny funkcionálních jazyků

Ne tak důležité: jakprogram počítá (akce)

–Programy bývají náročné na systémové prostředky (paměť a procesorový čas)

• Např. QuickSortv jazyce C# provede seřazení prvků „na místě“ (nepotřebuje žádnou paměť navíc)

Logické programování

Logické programování

• Patří do deklarativního paradigma

–Důraz: coprogram počítá (vztah vstup–výstup)

–Ne tak důležité: jakprogram počítá (akce)

• Výpočet pomocí logického odvozování(hledání důkazu)

–Většinou se používá tzv. predikátová logika prvního řádku

• Asi nejpopulárnější jazyk:

–Prolog

Prolog

• Prolog(programovací jazyk)

–Vznik 1972

–Název pochází z „PROgrammationenLOGique“ (francouzsky „programování v logice)

–Pro vyzkoušení doporučuji:

• SWI-Prolog

–http://www.swi-prolog.org/

• SWI-Prolog-Editor (jen Windows)

–http://lakk.bildung.hessen.de/netzwerk/faecher/informatik/swiprolog/indexe.html

Prolog: použití

• Komerční sféra:

–Zpracování přirozeného jazyka

• Projekt Clarissapro Mezinárodní vesmírnou stanici (NASA)

–Řídící systémy, expertní systémy, systémypro podporu rozhodování

• FleetWatch(letectví)

• ARGOS (systém pro podporu rozhodování a krizové řízení –incidenty zahrnující chemické, biologické, radiologické nebo nukleární úniky)

Objekty a vztahy

• Prolog lze použít pro řešení problémů, které zahrnují

–Objektya

–Vztahymezi těmito objekty

• Příklad:

–Pepa má knihu.

• Vztah: vlastnictví („má“)

• Objekty: Pepa, kniha

• Vztah je jednosměrný (kniha nemá Pepu).

Pravidla

• Pravidlapopisují vztahy pomocí jiných vztahů

• Příklad:

–Dvě osoby jsou sestry, pokud jsou obě ženy a mají stejné rodiče.

Dotazy

• Dotaz na existenci určitého vztahu

–Odpověď: ano(pravda), nebo ne(nepravda)

• Příklady:

–Má Pepa knihu?

–Jsou Lenka a Hanka sestry?

Programování v Prologu

• Programování v prologu:

–Deklarace faktů (o objektech a vztazích mezi nimi)

–Definování pravidel (dtto)

–Kladení dotazů (dtto)

• Program = skladiště (databáze) faktů a pravidel


 

 


 

Zápis dotazů

 

Interaktivní dotazovací režimu Prologu je indikován výzvou ?-


 

 

Růžové číslo je zde jen číslo řádku (příkazu), tj. nic podstatného

= Má Pepa knihu?

Odpověď (pravda/nepravda) je vždy vztažena kdatabázi. Výsledek je tedy nutné chápat ve smyslu „je/není odvoditelné z databáze“.


Proměnné

 

Jména proměnných musí začínat velkýmpísmenem. Více výsledků


 

 

Prolog vypíše jen první výsledek, hledání dalších výsledků se povolí stiskem; (středníku), ukončení je.(tečka).U pravidel Prolog jako poslední výsledek vypíše false.

 

Proměnné –hledání řešení

• Prolog při hledání řešení (důkazu) používá následující postup:

–Prochází dotaz postupně zleva doprava

–Prohledávání do hloubky(backtracking)

• Strom možností

• Jednotlivá „patra“ stromu odpovídají proměnným vdotazu (X, Y, Z, …)

–Jednotlivé možnosti v rámci patra odpovídají různým možným hodnotám dané proměnné

Prohledávání do hloubky

• Konkrétněji:

–Najde první shodu pro X (unifikace)

• Vyhodnocuje dále zbytek dotazu, přičemž předpokládá, že X má právě tuto hodnotu. Pokud narazí na jinou proměnnou (Y, Zapod.), postupuje stejný způsobem –zanoření o jednu další úroveň. Pokud pro takové X(Y, Z, …) najde řešení (důkaz), ohlásí ho.

–Pokud řešení (důkaz) pro dané Xnenašel, najde další možnou shodu pro X

• Vyhodnocuje dále zbytek dotazu, přičemž předpokládá, že X má právě tuto novou hodnotu.

–Atd.

Proměnné –hledání řešení

• Proč by nás mělo zajímat, jak Prolog hledá řešení? Záleží na tom?

–Argument: Pokud je dotaz/pravidlo logicky správně, pak Prolog přeci musí vždy dojít ke správnému výsledku

• To je pravda, ale vhodnou formulací dotazu/pravidla:

–Lze hledání důkazu urychlit

• Strom všech možností (všech možných hodnot proměnných), se bude procházet efektivněji

–Lze předejít tomu, aby se hledání důkazu zacyklilo (a skončilo pro nedostatek paměti)

• Strom všech možností totiž může být i nekonečný, např. při využití rekurze v pravidlech (viz cvičení)


 

Pravidla (sestry)


Dvě osoby jsou sestry, pokud jsou obě ženy a mají stejné rodiče.

 

SLOŽITĚJŠÍ PŘÍKLAD


 

 

 


 

Nástroje CASE

Automatizace vývoje SW

• Automatizace vývoje software –Metodiky vývoje software

• Vodopádový model, prototyping, přírůstkový, spirálový, RAD, … –Diagramy (např. UML)

• Diagram tříd, komponent, aktivit, stavový diagram, sekvenční diagram, …

Nástroje CASE

• CASE= ComputerAidedSoftware Engineering

• Komplexní programové systémy pro podporu vývoje softwarové aplikace

–V jednotlivých jeho fázích

–Některé funkce mohou být integrovány dovývojového prostředí (IDE)

Rozdělení podle fáze (1/3)

• PreCASE –tvorba globální strategie

• UpperCASE –plánování, specifikace požadavků, modelování organizace podniku

–Cíl: analýza organizace    řízení projektů, sledování ekonomických ukazatelů, rámcová specifikace požadavků, …

–Dle metodiky vývoje software

Rozdělení podle fáze (2/3)

• MiddleCASE –detailní specifikace požadavků, vlastní návrh systému, vizualizace, dokumentace

–Procesy, datová úložiště, správa dokumentů a konfigurace, vývoj prototypů, návrh uživatelského rozhraní

–Diagramy tříd, stavové diagramy, …


 

–Generátory UI (obrazovky, tiskové sestavy), generátory kostry definic dat

Rozdělení podle fáze (3/3)

• LowerCASE–kódování, testování, údržba

–Reverzní inženýrství

• Zjištění modelu z již existujícího kódu/dat

–Generování kódu

–Řízení testování

–Sledování a vyhodnocování práce systému, vyhodnocování metrik

• Post CASE–zavedení, údržba a další rozvoj systému

Funkce CASE (1/4)

• Centrální úložiště(databáze, slovník, repository)

–Datové struktury a jejich vzájemné vztahy

–Kontrola kvality (konzistence, normalizace)

• Například:

–Odvozování (generování) vztahů/dat

–Upozorňování na chybějící data (definice)

–Upozorňování na špatná data (nekonzistence)

–Mazání odkazů na odstraněný objekt

–Zabránění nekorektním akcím s daty

Velké projekty = více lidí    potřeba podpory práce v týmu

–Komunikace přes síť (zpravidla client-server)

• Výměna dokumentů atd.

–Centrální úložiště

• Verzování

• Řízení přístupu (přístupová práva)

• Replikace, synchonizace

–Řízení týmové práce

• Evidence, úkoly, odhadování pracnosti (metriky), … Generování:

–Kostry zdrojového kódu a struktura dat

• Např. hlavičky funkcí, definice tříd, rozdělení na moduly, databázové schéma atd.

–Aplikačních rozhraní (komponent)

–Uživatelských rozhraní aplikace

• Obrazovkové formuláře

• Tiskové sestavy

• Lze ukázat zákazníkovi (prototyping)

–Dokumentace Modelování, vizualizace

–Struktura podniku

–Projekty, procesy

–Datové struktury a vztahy mezi nimi

–Diagramy…

Model ↔ kód

• Forwardengineering(dopřednéinženýrství)

–Model (diagram)    kód (program, SQL)

• Reverse engineering(zpětné inženýrství)

–Kód   Model (diagram)

• Synchronizacemodel ↔ kód

–Když udělám změny v modelu

–Když udělám změny v kódu

Jde jen o nástroje

• Nezaručí bezchybný vývoj aplikací

• Můžou vyžadovat velice odborné znalosti

–Např. při analýze, modelování, …

• Nutno posoudit vhodnost použitých metod, na kterých je CASE založen

Příklady CASE nástrojů

• SybasePowerDesigner

• RationalRose (IBM)

• SelectArchitect

• EnterpriseArchitect(SparxSystems)

• Oracle Designer

• ArgoUML(freeware)


 

UKÁZKA NÁSTROJE CASE

MySQLWorkbench MySQLWorkbench5.2.47

–CommunityEdition(zdarma –GNUGPL)

–http://dev.mysql.com/downloads/tools/workbench/5.2.html

• ZIP Archive, 30 MB

• Ukázka:

–Data Modeling: EER* diagramy EER Model

• Data Modeling    CreateNew EER Model     Adddiagram

• Ovládání:

–Placea New Table = T

–Edit table = dvojklik na záhlaví tabulky

• Nastavení zobrazení:

Ukázka: knihovna

• Databáze pro knihovnu:

–Knihy (identifikovány pomocí ISBN)

–Autoři (identifikováni číslem)

–Informace o knize

• Velká data, proto v samostatné tabulce

–Jednotlivé výtisky knihy

• Použité datové typy:

–INT = celé číslo

–CHAR(13) = 13znaků

–VARCHAR(200) = až 200 znaků


Knihovna

 

 

Vztahy mezi tabulkami

 

Vybrat typ vztahu, klepnout na záhlaví jedné tabulky, klepnout na záhlaví druhé

• Kardinalita vztahu:

–Kniha a Výtisk = 1 : n

–Kniha a Autor = n : m

–Kniha a Knihainfo= 1 : 1(identifikující)

• Realizaci vztahu zařídí program:

–Přidáním cizího klíče

–Vytvořením nové tabulky

Vztahy mezi tabulkami

Vztahy mezi tabulkami

 

Pokud se spleteme (např. vztah 1 : n uděláme naopak), lze vztah jednoduše odstranit

–Pravým tlačítkem na čáru vztahu    Delete

–Program umí automaticky odstranit příslušný cizí klíč:


 

Vizualizace, editace

• Vizualizace (přehlednost):

–Můžu si tabulky rozdělit do skupin (layers)

–Export jako obrázek (PNG, SVG)

• Lze poslat/ukázat zákazníkovi…

• Editace:

–Pokud se spleteme, můžeme poslední akci vrátit (Edit    Undo)

Ukázka skupin

Forward/ reverse engineer

• Generování SQL kódu do souboru:

–File  Export    ForwardEngineerSQL CREATE Script

• Práce s živou databází*:

–Database  ForwardEngineer

• Vytvoří tabulky v databázi (podle diagramu)

–Database  Reverse Engineer

• Načte strukturu tabulek z databáze a vytvoří podle ní model (diagram)

 


* Vyžaduje mít spuštěnou databázi
MySQL