# Porovnání objektového a procedurálního programování

- Programovacích stylů je celá řada
	- Mezi nejběžnější styly patří v současné době objektové a procedurální programování 

### Základní charakteristiky obou přístupů

- Oba přístupy se v některých aspektech podobají a v některých liší 

#### Objektové programování

- Java, kterou jsme se celý semestr zabývali, je primárně objektový jazyk
- V objektovém programování je řešený problém dekomponován na objekty představující objekty z reálného světa
- Zdrojový kód je tak členěn na třídy, které obsahují atributy (data) a metody (podprogramy – procedury a funkce), které se těmito atributy pracují
	- Podle třídy lze vytvořit libovolné množství instancí (objektů), každá s vlastním nastavením hodnot atributů
- Díky použití objektů je program lépe členěn na víceméně samostatné jednotky (třídy)
	- Lepší znuvupoužitelnost kódu
	- Třída se poměrně snadno dá použít v jiném v jiném programu, protože je oddělená od dalších tříd
- Zapouzdřenost + jasně stanovená identita
	- Díky přístupovým právům (viz Kap. 14.7.1) je zajištěn kontrolovaný přístup k datům (atributům) z vnějšku třídy
	- Vše někomu patří – metody a atributy (proměnné) jsou vždy součástí tříd
- Kromě zapouzdřenosti existují dva další pilíře objektového programování
	- Skládání (objekt obsahuje jiné objekty) a polymorfizmus
	- Viz předměty KIV/PPA2 a KIV/OOP
- Objektové programování nabádá programátora k větší disciplíně
	- Obsahuje více pravidel, která by se měla dodržovat
	- Při jejich dodržení by měla vést k přehlednějšímu zdrojovému kódu
- Objektové programování nabádá k dekompozici problému (na objekty)

#### Procedurální programování

- V procedurálním programování je problém dekomponován na jednotlivé činnosti
- Program tvoří jeden celek (ač může být často rozdělen do několika jednotek / zdrojových souborů – modulů) členěný na podprogramy (procedury a funkce)
- Procedury a funkce rovněž pracují s daty, ale nejsou s nimi přímo svázány v jednom celku jako v objektovém programování
	- Procedury a funkce jsou umístěny „volně“, nejsou v žádné třídě
	- Pro jednoduché problémy mohou být programy kratší, protože není potřeba vytvářet třídy
- Procedurální programování dává programátorovi větší volnost
	- Pravidel je méně než v objektovém programování
	- Pro složitější programy může být zdrojový kód méně přehledný (ale nemusí – záleží na programátorovi) 
- Kombinace více přístupů
	- Mnohé jazyky umožňují programovat jak procedurálně, tak objektově (a případně mohou obsahovat další přístupy)
		- Programátor pak může kombinovat oba přístupy nebo používat jen jeden z nich podle svého uvážení
		- Např. C++, PHP, Pascal (FreePascal, Delphi) 

### Jednotlivé rozdíly

- V následujících kapitolách budou ukázány hlavní rozdíly mezi objektovým a procedurálním programování
	- Aby nebylo nutné učit se syntaxi nějakého procedurálního jazyka (např. C), budou příklady na procedurální programování ukázány v Javě
- Procedurální programování v Javě
	- Java je primárně objektový jazyk a byla tak koncipována od svého vzniku
	- Přesto je v ní možné „simulovat“ procedurální programování
		- Celý program napsat do jedné třídy
			- Další třídy používat pouze jako strukturovaný datový typ
		- Používat pouze statické metody
	- POZOR!
		- Tento postup je použit pouze pro porovnání principů objektového procedurální programování
	- Neznamená to, že by se tak v Javě mělo programovat

#### Metody, procedury a funkce

- V procedurálním i objektovém programování jsou části výkonného kódu rozděleny do podprogramů, které je možné (opakovaně) volat v jiných částech kódu 
	- V objektovém programování se nazývají metody
		- Lze je rozdělit na procedury (nemají návratovou hodnotu) a funkce (mají návratovou hodnotu)
	- V procedurálním programování se nazývají rovnou procedury (nemají návratovou hodnotu) a funkce (mají návratovou hodnotu)
	- Toto je pouze rozdíl v terminologii
- Metody v objektovém programování
	- Jsou součástí konkrétní třídy
	- Metody instance
		- Při dobrém návrhu většina metod
		- Volají se nad konkrétní instancí
		- Mají přístup k atributům instance => díky tomu mají obvykle menší počet formálních parametrů (poměrně často nemají žádné parametry)
	- Metody třídy
		- Je možné je volat bez vytvoření instance
		- Nemají přístup k atributům instance
		- Data, se kterými mají pracovat, musí být do metody předány přes její formální parametry
			- Nebo mohou pracovat s proměnnými třídy
			- Nebo mohou pracovat s tzv. „globálními“ proměnnými 
		- Jsou velmi podobné procedurám a funkcím v procedurálním programování
- Procedury a funkce v procedurálním programování
	- Volají se přímo jen svým jménem a skutečnými parametry
	- Data, se kterými mají pracovat, musí být do procedury/funkce předány přes její parametry
		- Nebo mohou pracovat s „globálními“ proměnnými
- Předávání parametrů do metody (procedury či funkce)
	- Předání parametrů odkazem
		- Ve formálním parametru se předá proměnná a s její hodnotou se v metodě (proceduře či funkci) pracuje
		- Změna hodnoty provedená v metodě se projeví i vně metody
	-  Předání parametrů hodnotou
		- Ve formálním parametru se předá kopie hodnoty proměnné a s touto hodnotou se v metodě (proceduře či funkci) pracuje
		- Změna hodnoty provedená v metodě se neprojeví vně metody, protože se mění kopie
		- Tento postup používá Java (a mnoho dalších jazyků)
	- Způsob, který se použije, nezáleží na tom, zda se jedná o procedurální nebo objektové programování
		- Způsob závisí na konkrétním jazyce 
		- Některé jazyky umožňují jeden nebo druhý způsob, přičemž druhého (neumožněného) způsobu je obvykle možno nějak dosáhnout
		- Některé jazyky explicitně umožňují oba způsoby (např. C#, Pascal) 
	- Těla metod (procedur či funkcí)
		- Těla metod, procedur a funkcí se v obou přístupech (objektový a procedurální) nijak neliší
		- V obou případech obsahují výkonný kód metody (tj. příkazy, které provedou činnost metody/procedury/funkce)

#### Globální proměnné

- V procedurálním programování je potřeba předat všechna potřebná data do procedur a funkcí pomocí parametrů
	- Na rozdíl od objektových jazyků, kde metody instance mají přístup k atributům instance
- Často však také existuje možnost mít tzv. „globální proměnnou“, která je viditelná ve všech procedurách a funkcích programu
	- Tato možnost často existuje v procedurálních i objektových jazycích explicitně (např. PHP), nebo se dá různými způsoby dosáhnout
	- Např. v Javě jsou veřejné (statické) proměnné třídy viditelné odevšad
		- Mimo třídu, kde jsou definovány, je potřeba volat je s názvem třídy
	- Obecně platí, že metody, procedury a funkce mohou s takovou proměnnou pracovat, pokud není zastíněná lokální proměnnou se stejným jménem

#### Homogenní strukturované datové typy (pole)

- S poli se pracuje v podstatě stejně, bez ohledu na to, zda používáme procedurální či objektové programování
- Konkrétní implementace pole závisí spíše na programovacím jazyku než na přístupu k programování
	- Např. v Javě je pole instance speciální třídy, která kromě samotných prvků obsahuje i délku pole a další data
	- Např. v C je pole jen posloupnost prvků stejného typu, které jsou umístěny za sebou v paměti počínaje určitou adresou  délka pole není v poli uložena
- POZOR!
	- Pokud v daném jazyce není součástí pole i jeho délka, je potřeba mít délku uloženou zvlášť (typicky v celočíselné proměnné)
	-  Nutné, abychom věděli, jak je pole dlouhé a nedostali jsme se při práci s polem mimo platné indexy

#### Heterogenní strukturované datové typy

- Pokud je v objektovém jazyce potřeba uložit data různých datových typů do jednoho celku, použije se typicky objekt (instance třídy)
- V procedurálním jazyce objekty nejsou, ale možnost ukládat heterogenní data do společných celků typicky existuje 
	- Typicky se používají strukturované datové typy, které mají položky různých datových typů (podobně jako atributy instance), ale neobsahují žádné metody
	- Lze si je představit jako třídy s veřejnými proměnnými instance bez metod
	- Běžný obecný název je záznam (record) nebo struktura (struct) 
		- Konkrétní názvy a způsob deklarace se liší jazyk od jazyka 