Lekce 3 - Třívrstvá architektura a další vícevrstvé architektury
V minulé lekci, Monolitická a dvouvrstvá architektura, jsme si vysvětlili, co je to logická architektura a proč je důležité, aby naše aplikace nějakou architekturu měly. Zmínili jsme si monolitickou architekturu a tu poté rozdělili na dvě vrstvy, čímž vznikla architektura dvouvrstvá. Pro zažití principu kontrolerů a modelů jsme vytvořili plně funkční dvouvrstvou aplikaci v PHP, která poskytuje API pro získávání dat o automobilech.
Třívrstvá architektura
Dostáváme se opět k tématu, které padá na většině pracovaních pohovorů. Otázku "Co je to třívrstvá architektura?" určitě zaslechnete. Jelikož jsme si již vysvětlili architekturu dvouvrstvou, nečeká nás toho příliš nového. Ona třetí vrstva zprostředkovává právě zobrazení výsledku uživateli, což jsme mohli u dvouvrstvé aplikace zanedbat, jelikož posílala jen JSON kód pro stroj.
Vrstvy aplikace budou:
- Modely - Logika, typicky SQL dotazy
- Views (pohledy) - Šablony, typicky HTML soubory
- Controllers – Prostředníci, se kterými komunikuje uživatel a kteří komunikují s modely a pohledy. Právě prostředník umožňuje plné oddělení logiky a zobrazení. O toto se v každé aplikaci snažíme. Jestli si máte něco zapamatovat, tak že architektury většinou oddělují logiku a zobrazení.
Všimněte si, že počáteční písmena vrstev dávají dohromady "MVC", což je označení nejznámější třívrstvé architektury. Další třívrstvé architektury jsou např.:
- Model-View-ViewModel (MVVM) - Architektura MVVM přináší další vrstvu. Pro lepší předávání dat mezi šablonou a kontrolerem a opačně používáme minimalistické modely určené pro šablony, tzv. ViewModely. V praxi zde funguje binding, což je poměrně sofistikovaný nástroj. Umožňuje nám navázat ViewModel na šablonu tak, že se jakákoli změna např. hodnoty ve formuláři šablony okamžitě projeví změnou této vlastnosti ve ViewModelu a naopak. Pouhým vytvořením ViewModelu jsme tedy schopní číst a zapisovat data v šabloně.
- Model-View-Presenter (MVP) - Architektura MVP je v našich končinách propagována zejména populárním PHP frameworkem Nette. Funguje v podstatě stejně jako MVC, někdy je chápána jako implementace MVC. MVC i MVP může být chápáno a implementováno v různých aplikacích různým způsobem, mezi konkrétními vzory tedy existují malé rozdíly. V MVP je často umožněno volání z view na presenter. Někdy je uváděno, že view přebírá samotné řízení aplikace a vytváří si presenter, kterým si tahá data z logiky. Nutně tak ovšem fungovat nemusí. Pokud jste se v MVC a MVP zamotali, je to bohužel správně, protože jejich specifikace je matoucí. Doporučuji se řídit spíše dříve uvedeným MVC.
Pojďme si pro jistotu ještě jednou popsat, co budou jednotlivé vrstvy dělat:

Životní cyklus požadavku na třívrstvou MVC aplikaci bude následující:
- Router dle URL zavolá kontroler
- Kontroler se dotáže na data modelu
- Data si kontroler uloží
- Data předá View
- View vyplní daty HTML šablonu
- Sestavená stránka je odeslána uživateli
Případně se můžete podívat na detailní článek MVC architektura.
Pojďme z naší dvouvrstvé aplikace udělat aplikaci třívrstvou, tedy aby zobrazovala výsledky jako HTML stránky.
Modely/SpravceAut.php
Model bude stále stejný.
Kontrolery/AutaKontroler.php
Kontroler místo vypsání dat pomocí echo()
a
json_encode()
připraví proměnné pro šablonu a následně
šablonu načte:
class AutaKontroler { private $spravceAut; private $databaze; public function __construct($databaze) { $this->databaze = $databaze; $this->spravceAut = new SpravceAut($this->databaze); } public function vsechna() { $auta = $this->spravceAut->vratAuta(); // Proměnná pro šablonu require('Sablony/auta.phtml'); // Načtení šablony } // Případné další akce jako jedno($id), odstran($id), ... }
Sablony/auta.phtml
Onou novou vrstvou aplikace je nyní view, tedy šablona. To je HTML kód s
co nejnižší příměsí syntaxe nějakého dalšího jazyka, pomocí které
se v šabloně iteruje nad daty a vkládají se do ní proměnné. My zde
pomocí cyklu proiterujeme proměnnou $data
, kterou jsme získali
od kontroleru.
<html lang="cs"> <head> <title>Výpis automobilů</title> <meta charset="UTF-8"> </head> <body> <table border="1"> <?php foreach ($auta as $auto) : ?> <tr> <td><?= htmlspecialchars($auto['spz']) ?></td> <td><?= htmlspecialchars($auto['barva']) ?></td> </tr> <?php endforeach ?> </table> </body> </html>
Hotová šablona je následně odeslána uživateli. Vypadají takto:

S naší ukázkovou aplikací jsme trochu pohnuli. Závislosti jsme sice předávali zatím ručně, ale aplikace je nyní rozdělená na:
- Models - Soubory s čistou aplikační/obchodní logikou
- Views - Soubory s relativně čistou šablonou
- Controllers - Relativně malé prostředníky
Můžete si pokrok srovnat s příkladem, kdy bylo vše v jednom souboru. Je nutné si ovšem představit, že je každá část dostatečně komplexní, aby byla patrná přidaná hodnota oddělení těchto částí.
Formulářové aplikace
A co formulářové aplikace? Pokud aplikace není webová, ale např.
desktopová, samozřejmě zde opět zafunguje nějaká automatika nad naším
kódem, která zavolá tu danou třídu pro ten daný formulář nebo cokoli
prostřednictvím čeho uživatel komunikuje. Vzor kontroler lze opravdu
aplikovat úplně všude a měli bychom tak také učinit. Určitě jste
nějakou formulářovou aplikaci někdy vytvořili, třída obsahující obsluhu
onoho formuláře byla kontroler. Např. v JavaFX se
třída i tak opravdu jmenuje, ale např. v C# se nazvaly CodeBehind, i když se
jedná o kontrolery. Přiznejte se, psali jste logiku přímo do tohoto souboru
obsluhujícího formulář?
Tak nyní již víte, že byste zde měli maximálně vytvořit modely a volat
logiku zapouzdřenou v těchto modelech. Stejně jako jsme si to nyní ukázali
na webové aplikaci s auty.
Pokud vám MVC dělá problémy nebo vás naopak zaujalo, podívejte se na náš samostatný kurz k této architektuře v PHP - Jednoduchý redakční systém v PHP objektově (MVC) nebo na obecný článek popisující tuto architekturu - MVC architektura.
V příští lekci, Špatné způsoby předávání závislostí - Statika, se budeme konečně věnovat předávání závislostí. Ukážeme si, co se stane, když závislosti nebudeme předávat vůbec, ale budeme tvořit stále nové instance služeb. Dále si ukážeme anti-patterny jako předávání statickými atributy, návrhovým vzorem Singleton, vzorem ServiceLocator a různými variacemi.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 73x (8.64 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP