11. díl - Statika v PHP do třetice

PHP Objektově orientované programování Statika v PHP do třetice American English version English version

V minulém tutoriálu o objektově orientovaném programování v PHP jsme pokračovali v popisu třídních prvků a uvedli jsme si konstanty. Dnešním dílem téma statiky uzavřeme, vysvětlíme si statický registr, databázový wrapper a nakonec budeme polemizovat o tom kdy statiku použít.

Statický registr

Statický registr je třída, ve které jsou jen statické proměnné, obsahující nějaké hodnoty. Typicky se taková třída používá pro uchování nastavení aplikace. Je potom sdílená v celé aplikaci a obsahuje např. heslo k db, url webu, výchozí jazyk a podobně. V neobjektových aplikacích se místo statického registru používaly globální proměnné. Třída by mohla vypadat např. takto:

class Nastaveni
{
        public static $udajeDB = array(
                'jmeno' => 'root',
                'heslo' => ''
        );

        public static $url = 'localhost';

        public static $jazyk = 'cz';

}

V celé aplikaci se potom můžeme např. ptát na nastavený jazyk nebo toto nastavení změnit:

if (Nastaveni::$jazyk != 'cz')
        $pozadi = "pozadi_anglicke.png";

Použití statického registru je opět velmi kontroverzní. K uložení konfigurace aplikace není špatný, bývá však velmi často používán k uložení různých instancí objektů, se kterými se v aplikaci dále pracuje. Všechny objekty jsou potom přístupné odevšuď přes registr a to je prostě špatně. Je otázka, jestli se dá o takové aplikaci potom vůbec mluvit jako o objektové.

Databázový wrapper

Poměrně časté a i smysluplné použití statiky je pro databázový wrapper. Asi jste doteď pracovali se zastaralými neobjektovými databázovými ovladači (např. funkce mysql_query() a podobně). V PHP se s databází pracuje objektově pomocí ovladače PDO (jako PHP Database Objects). Tento ovladač funguje tak, že se vytvoří instance třídy PDO a ta se připojí k databázi. Abychom se k databázi nemuseli připojovat stále znovu a znovu, sdílíme tuto jednu připojenou instanci v celé aplikaci. Právě k tomu použijeme statiku. Protože jsme dlouho nedělali nic praktického a práce s databází je velmi důležitá, zkusíme si to hned příští lekci, kde si tvorbu wrapperu i lépe popíšeme.

Kontroverze

Jak jsem se již zmínil na začátku tohoto trojčlánku o statice, statika je jedno z nejkontroverzněj­ších témat objektově orientovaného programování. Když se nad tím zamyslíte, tak v podstatě narušuje jeho koncept, jelikož statické prvky jsou přístupné odkudkoli a bez instance. Když máte v aplikaci pár statických tříd (třeba 4) a zbytek normálních, je vše v pořádku. Jakmile ale máte každou druhou třídu statickou, je někde problém.

Vždy platí, že každou aplikaci lze napsat čistě objektově bez použití statiky. Někteří programátoři dokonce zastávají názor, že statiku by jazyky vůbec neměly obsahovat. Samozřejmě to není tak horké, nicméně statika je velmi často špatně užívána a proto zbytek článku věnuji rozebrání správných a špatných využití této techniky.

Správné použití statiky

Když se zamyslíte, udělali jsme si tu několik příkladů a všechny měly společné určité rysy. Jednalo se o pomocné metody nebo pomocné třídy, které se často používají na více místech v aplikaci. Ze třídy často nemá smysl vytvářet instanci a kdyby to šlo, chtěli bychom vždy jen jednu (jednu Matematiku, jednu konzoli, jednu databázi...). V objektových redakčních systémech se staticky často píší také tzv. helpery, což jsou krátké pomocné metody pro formátování výstupu. Na ITnetwork.cz máme např. takový helper, co vypíše vybrané datum slovy:

echo('Dnes je :' . DatumHelper::slovy($datum));

Dalším příkladem byla ona matematická knihovna, ta dokonce nemá žádný vnitřní stav a jedná se pouze o skupinu pomocných metod.

Do statické proměnné nějaké třídy můžeme také uložit instanci aktuálně přihlášeného uživatele, aktuálně zobrazeného článku a podobně. To jsou opět věci, které je potřeba sdílet v mnoha třídách.

Statika v uznávaných projektech

Statiku nalezneme v základních objektových knihovnách uznávaných programovacích jazyků, jako jsou např. Java nebo C# .NET. Statika je zde použita přesně pro pomocné metody, jako zobrazení jednoduché zprávy nebo třeba vypsání textu do konzole:

Console::writeLine("Text");
MessageBox::show("Špatné heslo");
$vysledek = Databaze::dotaz("SELECT * FROM `clovek`");

Konzoli máme jen jednu a pracujeme s ní ve velkém počtu tříd, proto dává smysl mít její třídu jako statickou. Podobně je to s databází, aplikace téměř vždy používá právě jednu databázi a to z mnoha míst.

Špatné použití statiky

Když se budete rozmýšlet, zda máte statiku použít, tak ji raději nepoužívejte :) Na 90% je totiž zbytečná. Statiku byste neměli používat v jiných případech než ve výše zmíněných. Pokud nevytváříte nějakou systémovou třídu, která se bude používat všude, určitě by neměla být statická.

I např. třída, která slouží ke správě lidí a obsahuje metody jako registruj(), vymaz() a podobně by neměla být statická a je lepší, když si vždy, kdy potřebujete s lidmi pracovat, vytvoříte její instanci. Třída by se mohla jmenovat třeba SpravceLidi. Nemělo by vás napadnout udělat ani statickou galerii, statické lidi a podobně. Celé tyto 3 články jsem psal hlavně proto, abyste statický kód uměli číst. Neznamená to, že ho máte psát a určitě budete často narážet v cizím kódu na statické prvky, které by statické být neměly.

Předávání závislostí a dependency injection

Statika se používá většinou k předávání závislostí, tedy tříd, které potřebují ostatní třídy k tomu, aby fungovaly. Jedná se např. o již zmíněnou databázovou třídu nebo o nastavení aplikace. O řešení závislostí mezi objekty v aplikacích jsou napsané celé knihy a existuje milion přístupů. Je to jedno z nejřešenějších témat v objektově orientovaném programování. Těžko říci, jestli je pro začátečníky vhodnější statika nebo řešit závislosti pomocí návrhových vzorů, mně připadá statika jednoduchá a při rozumném použití i přehledná.

Většinou platí, že v systému do velikosti pár desítek tříd vám stačí občas použít statiku a aplikaci to nějak vážně neuškodí. Dělají to tak uznávané frameworky, dělám to tak i já. S většími projekty se zvyšuje počet závislostí (zejména když používáte knihovny třetí strany, což se snažím dělat minimálně) a tím i počet statických tříd. Jakmile v aplikaci staticky sdílíte více než pár prvků, je lepší od statiky upustit a předávat každé třídě např. v konstruktoru to, co potřebuje. Jen tak se aplikaci podaří uhlídat a nestane se spletí vzájemně provázaných statických tříd, kde člověk už neví co je na čem závislé. Právě z toho důvodu někteří programátoři doporučují statiku vůbec nepoužívat.

Technice předávání závislostí automaticky a bez statiky se říká Dependency Injection (zkráceně DI), více si o ní můžete přečíst např. v článku Dependency injection. Dalším řešením, které jsem si oblíbil zejména při tvorbě her, je vytvořit si sdílené instance v nějakém kontejneru a objektům poté v konstruktoru předávat tento kontejner (vzoru se říká service locator). Vyhneme se statice a např. ve hře se jednoduše ze třídy Hrdina dostaneme na instanci třídy Kontejner a přes něj na mapu, ostatní objekty, nastavení hry, databázovou třídu a podobně.

Jak řešit závislosti v reálném systému je ukázáno mimo jiné i dále, v navazujícím seriálu. Téma statiky jsme tedy probrali, příště si ukážeme základy práce s databází pomocí ovladače PDO.


 

  Aktivity (2)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (16 hlasů) :
4.8754.8754.8754.8754.875


 



 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!