Lekce 4 - Úvod do MVC architektury ve Spring Boot
V předchozí lekci, Vytvoření Spring Boot projektu v Javě, jsme si připravili vývojové prostředí pro Spring Boot. Také jsme poprvé spustili náš projekt.
Spring framework je postavený na MVC architektuře. Ta je velmi oblíbená na webu, ačkoli původně vznikla na desktopech. Je součástí populárních webových frameworků, jakými jsou kromě Spring Boot např. Symfony nebo Laravel pro PHP. V dnešním tutoriálu, který bude zaměřen více na teorii, si představíme principy MVC architektury. Osobně si bez ní (nebo nějakého podobného modelu) nedokážu představit složitější web.
Motivace
Základní myšlenkou MVC architektury je oddělení logiky od výstupu. Řeší tedy problém tzv. "špagetového kódu", kdy máme v jednom souboru (třídě) logické operace a zároveň renderování výstupu (HTML kód). Soubor pak například obsahuje databázové dotazy, logiku (Java kód) a různě poházené HTML tagy. Vše je do sebe zamotané jako špagety. Kód se samozřejmě špatně udržuje, natož rozšiřuje. Je špatně highlightovaný, protože si s ním IDE neví rady, HTML není správně naformátováno, ztrácíme se v jeho stromové struktuře.
Naším cílem je, aby zdrojový kód obsahující logiku vypadal jako zdrojový kód v Javě a výstup vypadal jako HTML stránka s co nejmenší příměsí dalšího kódu. S tím nám pomůže právě MVC architektura, která rozděluje tyto části na jednotlivé logické komponenty. Ty si teď postupně vysvětlíme.
Komponenty
Celá aplikace je rozdělena na komponenty 3 typů, jedná se o:
- Modely,
- View (šablony či pohledy) a
- Controllery (kontrolery).
Z toho také vychází název MVC. Neexistuje žádná striktní definice architektury, a tak se můžete setkat s více výklady. My se zaměříme na ten nejrozšířenější.
Pojďme si jednotlivé komponenty nejprve popsat.
Model
Model obsahuje logiku a vše, co do ní spadá. Mohou to být výpočty, databázové dotazy, validace a podobně. Pro nás to znamená, že modely jsou klasické Java třídy, jak jsme je znali doposud. Model vůbec neví o výstupu. Jeho funkce spočívá v přijetí parametrů zvenku a vydání dat ven. Zdůrazněme, že parametry nemyslíme URL adresu ani žádné jiné parametry od uživatele, ale parametry metod ve třídě modelu. Model neví, odkud data v parametrech přišla. Stejně tak neví, jak budou výstupní data zformátována a vypsána.
V kurzu budeme používat ORM (objektově relační mapování), modely potom
přímo korespondují s databázovými tabulkami. Podívejme se třeba na naše
stránky www.itnetwork.cz. Zde budeme mít
jako modely zajisté například třídu User
, Comment
a Article
. Instance modelů obsahují samozřejmě vlastnosti z
databáze. Např. instance modelu User
má vlastnost
name
. Třídě můžeme definovat instanční metody, např.
takovou, která vypočítá věk uživatele podle jeho data narození nebo
zjistí, kolik napsal komentářů v určitém časovém intervalu. Modely mohou
být také služby, např. CalculatorService
, který si v
pozdějších lekcích naimplementujeme.
Nyní máme představu, co model vykonává, pojďme se podívat na pohled (View).
View
Pohled (View) se stará o zobrazení výstupu uživateli.
Jedná se o HTML šablonu, obsahující HTML stránku a
tagy speciálního jazyka, který umožňuje do šablony
vkládat proměnné, případně provádět iterace (cykly) a podmínky. Vraťme
se k našemu příkladu. Pohled user.html
tedy vypíše detaily o
uživateli, pohled article.html
vypíše obsah článku.
Pohledů máme mnoho, např. pro funkcionalitu s entitou uživatele:
registration.html
, login.html
,
profile.html
a podobně. Pohled profile.html
je ale
již společný všem uživatelům a jsou do něj posílána různá data, vždy
podle toho, koho zrovna zobrazujeme. Tato data jsou poté dosazena do HTML
elementů šablony.
Šablony lze samozřejmě vkládat do sebe, abychom se neopakovali (šablona s layoutem stránky, šablona s menu a šablona článkem).
View není jen šablona, ale hlavně zobrazovač výstupu. Obsahuje tedy minimální množství logiky, která je pro výpis nutná (např. kontrola, zda si uživatel vyplnil přezdívku před jejím vypsáním nebo cyklus s komentáři, které se vypisují).
View podobně jako Model vůbec neví, odkud mu data přišla, stará se jen o jejich zobrazení uživateli.
Nyní se podíváme na poslední komponentu a tou je Controller.
Controller
Controller je nyní onen chybějící prvek, který osvětlí funkčnost
celé architektury. Jedná se o jakéhosi prostředníka, se
kterým komunikuje uživatel, model i view. Drží tedy celý systém pohromadě
a komponenty propojuje. Jeho funkci pochopíme z ukázky
životního cyklu stránky. Nejčastěji má každá entita jeden controller, v
našem příkladu máme tedy UserController
,
ArticleController
a tak dále.
Životní cyklus stránky
Životní cyklus zahajuje uživatel, který
zadá do prohlížeče adresu webu a
parametry. Tím nám sdělí, kterou podstránku si přeje zobrazit.
Pokud budeme chtít zobrazit detail uživatele s id 15
, bude URL
adresa vypadat třeba takto:
http://www.domena.cz/user/detail/15
Požadavek jako první zachytí mapping. Ten podle parametrů pozná, který controller voláme a požadavek mu předá.
Daný controller podle parametrů pozná, co se po něm
chce, tedy že má zobrazit detail uživatele číslo 15
. Zavolá
model, který uživatele vyhledá v databázi a vrátí
jeho údaje. Dále může zavolat různé metody modelu, např.
vypočítání věku uživatele. Tyto údaje si controller ukládá do
proměnných. V dalším kroku jsou View předány proměnné s
příslušnými daty. Controller tedy poslechl uživatele, obstaral podle
parametrů dotazu data od modelu a předal je view.
View přijme data od controlleru a vloží je do připravené šablony. Hotová stránka je zobrazena uživateli, který často o celé této kráse ani nic netuší
Celou situaci můžeme znázornit diagramem:
Dosáhli jsme tedy oddělení logiky od výstupu. Naše modely jsou napsány v Javě, view zase jako HTML. Komunikaci mezi modely, view a uživatelem nám obstarává controller. Kód je tedy díky MVC přehledný a logicky rozčleněný do jednotlivých souborů.
MVC architektura nám usnadňuje i myšlení při vývoji projektu. Když píši logiku, patří do modelu. Formátování a stylování výstupu řeším v šabloně. To, co uživatel chce, zjišťuji z parametrů pomocí controlleru. Tři různé problémy na třech různých místech, oddělené tak, aby do sebe nezasahovaly a nedělaly nám vývoj složitější.
V další lekci, Kontrolery a mapping v Java Spring Boot, si vytvoříme první menší aplikaci. Bude zdravit uživatele a také se naučíme používat mapping.