Slovník
Component, control, controller, snippet, presenter, modul a model. Jaký je mezi nimi rozdíl?
Mnoho začínajících programátorů s Nette má problémy s možnou rozdílností pojmů, které už znají odjinud. Úkolem tohoto postu je ujasnit chápání těchto pojmů a vyzdvidhnout alespoň nějaké základní rozlišovací prvky mezi nimi.
A taky zodpovědět otázku:
Proč se v příkladu Fifteen v distribuci Nette objevuje ve složce
components třída s názvem FifteenControl? ;)
Začneme tedy hezky od začátku.
Hierarchie
Dědičnost objektově orientovaného programování nám umožňuje třídy zařadit do hierarchické struktury, stejně jako je to v reálném světě. Můžeme totiž vytvářet nové třídy odvozením od jiných. Tyto odvozené třídy jsou pak potomkem původní třídy a dědí jeho členské proměnné a metody. Odvozená třída může (ale i nemusí) přidávat další funkcionalitu (metody a členské proměnné) k již zděděným schopnostem.
Ke správnému pochopení „jak věci pracují“, je potřeba vědět, kde má která třída své kořeny.
Object
|
--Component { IComponent }
|
--ComponentContainer { IComponentContainer }
|
--PresenterComponent { ISignalReceiver, IStatePersistent }
|
--Control { IPartiallyRenderable }
|
--Presenter { IPresenter }
Postupně si popíšeme všechny prvky této hierarchie a v závěru by mělo být jasné, jaké jsou rozdíly mezi jednotlivými pojmy uvedenými v úvodu.
Nette\Object
Na počátku všecho stál bůh. Tak je to (nebo se to aspoň říká) v reálném světě. V Nette místo boha máme „jen“ základní objekt, který sice žádnou speciální funkčnost nepřináší, ale zpříjemňuje nám komfort práce, obohacuje zápisy jazyku PHP věci, na které jsme zvyklí z vyspělejších jazyků (nebo spíš jazyků, které byly navrženy jako objektové a ne se jím staly až postupem času), a taky zachraňuje co vývojáři PHP zprasili.
Jako základní třída mnoha objektů v Nette hraje důležitou roli, protože v hierarchii stojí vždy nejvýše a používá se jako základní stavební prvek při tvorbě dalších tříd.
Viz také:
Komponenta (Nette\Component)
Komponenta se dá chápat více způsoby.
- Jednak je to komponenta, neboli díl, část, dynamický objekt webové stránky, který není závislý na okolním obsahu/objektech a dá se jednoduše volat a používat. Příkladem můžou být různé JS nebo Flashové prohlížeče obsahu určité složky, manipulátory s obrázky, search bar, menu, banner atd. V rámci jedné stránky jich může existovat libovolný počet. Tak bývají většinou chápány komponenty obecně lidmi pracujícími s webovými stránkami. Avšak je zde jeden zádrhel. Nette rozlišuje vykreslitelné a nevykreslitelné komponenty.
- Druhým způsobem, jak se dá v Nette chápat „komponenta“, je právě základní třída – Component. Jde právě o typ nevykreslitelné komponenty.
Když se nad tím zamyslíte, zjistíte, že ve výsledku oba pohledy myslí tutéž věc. Musíme ale rozlišovat onu vykreslitelnost a upřesnit ji.
Vykreslitelná komponenta je jakýkoliv objekt, který je potomkem třídy Control. Nevykreslitelná komponenta je právě taková třída, která dědí z třídy Component, ale zároveň už ne z třídy Control.
Naše nevykreslitelná základní třída Component implementuje rozhraní IComponent a je společným potomkem všech komponent, vycházejí z ní například všechny prvky formulářů. Obsahuje základní metody pro serializaci a unserializaci, několika reflexními metodami, které zjišťují hlavě příbuznost objektů a hlavně propojení (provázání) s rodiči.
Ve spojení s ComponentContainer disponuje možnostmi monitorovat změny jiných objektů a být na ně upozorněn (obdoba událostí z jiných jazyků).
Viz také:
- Component
- Component API reference
- IComponent API reference
Nette\ComponentContainer
ComponentContainer je základem uchovávání více objektů „na jednom místě“ a slouží jako skladiště pro objekty a jejich hierarchii, ve které můžou objekty díky svým metodám monitorovat změny jiných objektů, nebo dohledávat cesty k nim i ke svým rodičům a podobně. Podmínkou ale je, že tyto objekty budou dědit z Component.
Disponuje metodami pro snadné přidávání, získávání a odstraňování objektů a samozřejmě iteraci nad svým obsahem.
Tato třída také slouží jako rodič pro samotný formulář a třídy PresenterComponent, Control a Presenter.
Viz také:
- ComponentContainer
- ComponentContainer API reference
- IComponentContainer API reference
Nette\Application\PresenterComponent
Základní třída (rodič) pro všechny komponenty používané v Presenteru. Komponenty presenteru jsou persistentní objekty, které si Presenter uchovává počas svého životního cyklu.
Mají schopnost vzájemně ovlivňovat ostatní poděděné komponenty, ukládat své stavy jako persistentní (IStatePersistent) a odpovídat na uživatelské příkazy (ISignalReceiver), ale nejsou vykreslitelné.
Viz také:
- PresenterComponent
- PresenterComponent API reference
- ISignalReceiver API reference rozhraní
- IStatePersistent API reference rozhraní
Nette\Application\Control (Controller)
Pod pojmem controller je v jiných frameworcích, používajících návrhový vzor MVC, chápán právě prvek, který se stará o aplikační logiku (ono C z MVC).
Control (nebo Controller) v Nette je již zmiňovaná vykreslitelná komponenta.
Ta si umí navíc, kromě toho že se umí vykreslit, zapamatovat, jestli
při subrequestu došlo ke změnám, které si vyžadují jej překreslit.
K tomu slouží triptych metod invalidateControl(),
validateControl() a isControlInvalid(), což je
základem AJAXu v Nette.
Nette však nabízí ještě jemnější rozlišení, než na úrovni Controlů a to tzv. „snippetů“, nebo-li ústřižků.
Poznámka: pro jednoduchost k pochopení budu v následujících odstavcích brát Control jako komponentu. To že je vykreslitelná vyplývá z překreslovací vlastnosti snippetů.
Lze tedy invalidovat/validovat na úrovni těchto snippetů (každá komponenta může mít libovolné množství snippetů). Pokud se invaliduje celou komponentu, tak je i každý snippet považován za invalidní. Komponenta je invalidní i tehdy, pokud je invalidní některá její subkomponenta. Komponenta, která přijímá signál, je automaticky označena za invalidní.
Díky invalidaci snippetů přesně víme, které části kterých prvků bude potřeba překreslit.
Komponenta (tedy přesněji vykreslitelná komponenta Control) nepředstavuje pravoúhlou oblast ve stránce, ale logickou komponentu, která se může renderovat i do více podob. Každá komponenta může být navíc na stránce vykreslena vícekrát, nebo podmíněně, nebo pokaždé s jinou šablonou atd.
Viz také:
- Control
- Control API reference
- IPartiallyRenderable API reference
- Ajax & snippety – dokumentace k snippetům s příklady použití
Nette\Application\Presenter
Presenter reprezentuje instanci webové stránky. Obsahuje její aplikační logiku a podle příchozích požadavků spouští odpovídající akce.
Pomocí hierarchie OOP využívá možnosti všech svých předků a platí pro něj stejné vlastnosti, výhody ale i omezení.
Navíc je obohacen o možnosti tvorby redirectů a odkazů, přesměrování na kanonickou URL (definována Routama). Postupně jak prochází svým životním cyklem má možnosti ukládat hodnoty svých vnitřních stavů (persistentní parametry a komponenty), zpracovávát signály odeslané komponentami a patřičně na ně reagovat.
Viz také:
- Presenter
- Presenter API reference
- IPresenter API reference
Model a Modul
Model není je datový a zejména funkční základ celé aplikace. V modelu
je schovaná celá aplikační business logika. Je to ono M
z MVP (i MVC). Model si lze představit jako stavový
prostor, jako množinu různých stavů, do kterých se aplikace může dostat.
Jakákoliv událost, jakákoliv akce uživatele (přihlášení, odhlášení,
vložení zboží do košíku, změna hodnoty v databázi) představuje jen
přechod modelu z jednoho stavu do jiného. Je to černá skříňka, která si
uvnitř udržuje aktuální stav a ven nabízí pevně dané rozhraní.
Voláním funkcí tohoto rozhraní můžeme zjišťovat či měnit vnitřní
stav modelu. Přitom k rozhraní může přistupovat kdokoliv a kdykoliv. [1]
Oproti tomu pod pojmem modul se v Nette chápe balíček presenterů, komponent a šablon, ale i modelů, které dodávají presenteru data. Je to tedy určitá logická část aplikace. Například e-shop může mít tři moduly:
- katalog produktů s košíkem
- administrace pro zákazníka
- administrace pro provozovatele
Všechny tři moduly by ovšem mohly využívat stejných komponent a modelů. Potom se nabízí ještě chápat e-shop jako modul a výše uvedené tři moduly jako jeho submoduly. I to nám Nette umožňuje.
Použité citace a zdroje:
I) phpguru.cz –
Model není pouze databáze
