Slovník pojmů
Funkce
Funkce, anglicky function, odděluje jednu srozumitelnou činnost programu. Díky parametrům, návratovým hodnotám a jasnému názvu lze stejnou logiku opakovaně použít i samostatně otestovat.
Stručná definice
Vstup, práce a výsledek tvoří malý kontrakt.
Funkce sdružuje kroky, které spolu patří: vypočítá cenu položky, převede validovaný payload na datový objekt, rozhodne o přechodu stavu nebo sestaví odpověď. Její název má popsat účel a parametry spolu s návratovým typem mají říct, jaká data očekává a co vrátí.
Funkce nemusí být vždy čistý výpočet. Může uložit data, poslat zprávu nebo zavolat externí API, tedy vytvořit vedlejší efekt. Takovou odpovědnost je vhodné z názvu, typu návratové hodnoty, výjimky a okolního návrhu poznat. Výpočet ceny a odeslání e-mailu proto obvykle nemají být skryté ve stejné malé funkci.
K čemu slouží
Zapouzdřit jednu opakovatelnou činnost.
Dobře vymezená funkce snižuje opakování kódu a vytváří malé místo pro test, review a pozdější změnu pravidla.
- výpočet řádkové ceny, slevy nebo daně objednávky
- validace a převod vstupu z HTTP requestu na doménová data
- načtení konkrétního záznamu podle bezpečně předaného identifikátoru
- vytvoření API response nebo zprávy pro frontu
- malá infrastrukturalní operace, například odeslání requestu přes HTTP klienta
Praktický příklad
Výpočet ceny jedné položky objednávky
Funkce přijímá množství a jednotkovou cenu v haléřích. Typy popisují technický kontrakt, podmínka chrání doménové pravidlo, že objednávková položka musí mít kladné množství.
Volající dostane jen výslednou částku. Nemusí vědět, jak výpočet funguje, a test může ověřit běžný případ i neplatné množství bez databáze nebo HTTP requestu.
PHP
function calculateLineTotal(int $quantity, int $unitPriceInCents): int
{
if ($quantity < 1) {
throw new InvalidArgumentException('Množství musí být alespoň 1.');
}
return $quantity * $unitPriceInCents;
}
Jak funkce funguje
Od argumentů k výsledku nebo řízené chybě
Volání funkce je malý kontrakt. Čitelnost závisí na tom, zda jsou očekávání na vstupu a účinek funkce zřejmé.
- Volání Jiná část programu zavolá funkci a předá argumenty, například množství a jednotkovou cenu.
- Parametry Funkce pojmenuje přijaté hodnoty. Deklarace typů vymezí, jaké technické hodnoty mohou projít.
- Lokální práce Uvnitř vznikají proměnné a provede se jedna vymezená odpovědnost.
- Výsledek nebo výjimka Funkce vrátí hodnotu, dokončí vedlejší efekt nebo signalizuje stav, který volající musí řešit.
- Použití kontraktu Volající použije návratovou hodnotu a nemá záviset na interním postupu, pokud to kontrakt neslibuje.
Důležité pojmy
Parametr, argument a metoda nejsou stejná slova.
Přesná terminologie usnadní čtení kódu i domluvu při návrhu rozhraní.
Parametr a argument
Parametr je proměnná v definici funkce. Argument je konkrétní hodnota předaná při volání.
Návratová hodnota
return vrátí výsledek volajícímu. Funkce může mít i void návratový typ, pokud smysluplný výsledek nevrací.
Funkce a metoda
Metoda je funkce patřící třídě nebo objektu. Může pracovat se stavem objektu, a proto má jiný kontext než samostatná funkce.
Vedlejší efekt
Zápis do databáze, odeslání e-mailu, log nebo HTTP request mění svět mimo návratovou hodnotu. Nejde o chybu, ale účinek musí být zřejmý.
Výjimka
Výjimka signalizuje neočekávaný nebo neproveditelný stav. Nemá nahrazovat běžné větvení ani skrývat každou validaci.
Vztah k podobným pojmům
Funkce skládá chování, třída mu dává kontext.
Funkce, metoda, endpoint a job mohou být implementačně blízko, ale každé slovo popisuje jinou hranici odpovědnosti.
- Proměnná
- Funkce přijímá proměnné jako parametry a vytváří své lokální proměnné.
- Datový typ
- Typové deklarace určují technický kontrakt parametrů, vlastností a návratových hodnot.
- Třída a objekt
- Metoda patří třídě či objektu. Její chování může používat stav objektu, ale nemá z něj dělat skrytý univerzální vstup.
- API endpoint
- Endpoint přijímá HTTP request; uvnitř může volat více funkcí nebo aplikačních služeb. Endpoint není automaticky jedna doménová operace.
Výhody a omezení
Rozdělení na funkce má objasňovat, ne skrývat tok programu.
Přínosy
- jedno místo pro opakované pravidlo a jeho test
- jasný vstup a výstup pro volající kód
- menší funkce se lépe reviewují a mění
- oddělení čistého výpočtu od infrastruktury nebo vedlejšího efektu
Časté chyby
- funkce s nejasným názvem typu process nebo handle
- příliš mnoho parametrů, které signalizují chybějící datový objekt či odpovědnost
- skryté čtení globálního stavu nebo zápis do databáze bez zjevného názvu
- nadbytečné rozdělení jednoduchého výrazu do řetězce jednorázových wrapperů
Praktická hranice
Funkce má mít srozumitelný důvod ke změně.
Funkce je vhodná, když opakuje pravidlo, dává název důležitému kroku nebo odděluje část, kterou lze samostatně otestovat. Krátká funkce není cíl sama o sobě: několik řádků přímo v místě může být čitelnější než abstrakce, která nepřidává význam.
U složitější doménové operace bývá funkce součástí aplikační služby nebo objektu s jasnými závislostmi. Vstup přes dependency injection je čitelnější než samostatná funkce, která si potají vytváří databázové či HTTP klienty.
Na co myslet
Název, kontrakt a vedlejší efekt musí být čitelné.
Kvalita funkce se neposuzuje počtem řádků, ale tím, zda volající rozumí jejímu účelu, vstupu, výsledku a dopadu.
- použít slovesný název, který popisuje akci nebo výsledek
- typovat parametry a návratové hodnoty tam, kde to zpřesní kontrakt
- validovat business pravidla, která samotný typ vyjádřit neumí
- oddělit výpočet od sítě, databáze a jiných vedlejších efektů, pokud to zjednoduší test
- testovat výsledek a pravidlo, ne zbytečně každý vnitřní krok implementace
Časté otázky
Funkce v praxi
Je metoda a funkce totéž?
Metoda je funkce definovaná na třídě či objektu. Základní princip je stejný, metoda ale může pracovat se stavem a kontraktem daného objektu.
Musí každá funkce něco vrátit?
Ne. Některé funkce vykonají záměrný efekt a mají návratový typ void. I u nich má být z názvu a okolního kódu zřejmé, co provedou.
Nahrazují typy v parametrech validaci?
Ne. Typ int ověří technický druh hodnoty, ale sám neřekne, že množství musí být kladné nebo že uživatel smí upravit danou objednávku.
Je vždy lepší rozdělit kód do co nejmenších funkcí?
Ne. Rozdělení má přidat význam, opakovatelnost nebo testovatelnou hranici. Příliš mnoho jednorázových funkcí může zakrýt jednoduchý tok programu.
Jak pracuji s PHP v praxi
Aplikační logiku rozděluji podle skutečné odpovědnosti.
V backendových aplikacích propojuji malé testovatelné funkce s jasně vymezenými službami, daty a integračními hranicemi.