Úvod do architektury MVC

MVC je zajímavý fenomén – jeho popis najdete v tisících článků, a přesto kolem něj stále panuje víc zmatení než pochopení. Cílem této třídílné série proto bude podat poctivý, snad v něčem i unikátní úvod do světa MVC a souvisejících prezentačních vzorů. Dnes začneme obecnými principy architektury MVC.

Seriál: MVC a další prezentační vzory (3 díly)

  1. Úvod do architektury MVC 7.5.2009
  2. Prezentační vzory z rodiny MVC 11.5.2009
  3. Alternativy k MVC a závěrečné poznámky 15.5.2009

Architektura MVC (Model-View-Controller) v posledních letech dramaticky nabírá na popularitě, což je nejspíš způsobeno tím, že jednotlivé technologie již mají ranou fázi vývoje za sebou a vedle „základní výbavy“ se tak snaží nabídnout i prostředky pro tvorbu aplikací s kvalitní architekturou. Zend proto investuje nejen do PHP samotného, ale i do Zend Frameworku. Microsoft proto vytvořil nový webový framework ASP.NET MVC a i dalších nezávislých tvůrců MVC frameworků pro různé technologie jsou stovky. MVC je zkrátka žhavé téma současnosti, a to jsme teprve na začátku jeho nástupu do mainstreamu.

Architektura MVC má jednu zajímavou vlastnost: základní ideje člověk pochopí během pár minut, ale plně proniknout do všech detailů může trvat měsíce i roky. Jak se stává MVC populárnějším a populárnějším, na webu i v knihách se objevují jeho popisy, které se však podle mé zkušenosti spíše zaměřují na onu několikaminutovou část. Ucelených úvodů do MVC je málo a důsledkem je, že o MVC mají různí vývojáři různé představy a často narazíte na „MVC aplikaci“, která vlastně nemá s tímto vzorem vůbec nic společného.

Mým hlavním cílem proto bude popsat MVC a související prezentační vzory tak, abyste si odnesli co nejucelenější obrázek. Nečekejte vědecký popis s přísně formální strukturou, historickými údaji a podobně; články v této minisérii píšu tak, aby byly z pohledu vývojáře co nejužitečnější.

Pojďme tedy na to.

Motivace aneb problémy drag & drop vývoje

Protože dnes existují frameworky se stovkami předpřipravených komponent a protože tyto komponenty můžeme snadno uspořádat pomocí vizuálního návrháře v moderním IDE, lze snadno podlehnout iluzi, že tvorba UI je hračkou.

Ano, je, ale pouze do chvíle, než:

  • potřebujete najít bug v obrazovce, která má ve zdrojové podobě tisíce řádků kódu
  • máte zobrazit stejná data několikrát (např. seznam zákazníků a detail zákazníka)
  • potřebujete zajistit, aby se vám kód zbytečně neopakoval
  • potřebujete aplikaci pokrýt automatizovanými testy

V praxi a zvlášť na větších projektech proto rychle zjistíte, že pohodlí drag&drop vývoje vždy draze zaplatíte jinými komplikacemi, které se nejcitelněji projeví ve fázi údržby aplikace. Protože je tato fáze z pohledu životního cyklu aplikace nejdelší, nejnáročnější a tedy i nejdražší (i pokud „platíte“ pouze vlastním časem), téměř vždy se vyplatí oželet některé vymoženosti IDE a radši věnovat energii kvalitnímu návrhu aplikace.

V průběhu posledních desetiletí proto bylo popsáno několik architektonických vzorů pro prezentační vrstvu (zkráceně „prezentační vzory“, „GUI architektury“ a podobně), které řeší jedinou věc: jak udělat prezentační vrstvu co nejudržovatelnější. Právě o nich je celá tato minisérie.

MVC v pěti minutách

Jak jsem již zmínil, krása i zákeřnost architektury MVC spočívá v tom, že ji lze zdánlivě úspěšně vysvětlit jedním odstavcem. Posuďte sami:

Architektura MVC dělí aplikaci na 3 logické části tak, aby je šlo upravovat samostatně a dopad změn byl na ostatní části co nejmenší. Tyto tři části jsou Model, View a Controller. Model reprezentuje data a business logiku aplikace, View zobrazuje uživatelské rozhraní a Controller má na starosti tok událostí v aplikaci a obecně aplikační logiku.

Snadné, že? Jak se ale říká, ďábel je ukrytý v detailech. Při reálném vývoji budete řešit konkrétní otázky a sami sebe se budete ptát: Patří prezentační logika do View nebo do Controlleru? Patří funkčnost aplikace do Controlleru nebo do Modelu? Jak úzká vazba panuje mezi View a Controllerem? Má mít View přímou vazbu na Model? Tyto otázky jsou zajímavé tím, že z teoretického pohledu nejsou položeny moc dobře (jsou vágní a nejdou zodpovědět jednoznačně), ale ptají se přesně na věci, které programátor potřebuje řešit. Není v tom rozpor? Jak by bylo MVC užitečné, kdyby neumělo dát vývojáři konkrétní odpovědi na konkrétní otázky?

Zde se dostáváme k něčemu, co je pro pochopení MVC zásadní. Hned na začátku je totiž potřeba oddělit 2 věci:

  • MVC jako obecnou architekturu (přístup k tvorbě aplikací)
  • a potom jednotlivé variace MVC

Špatnou zprávou je, že variací je několik a že právě v jejich ovládnutí spočívá komplikovanost MVC, dobrou zprávou je, že právě konkrétní variace jsou vývojáři bezprostředně užitečné. Podrobně se jim proto budeme věnovat příště, nyní ale pojďme na popis MVC jakožto obecné architektury.

MVC pod drobnohledem

Už tedy víme, že architektura MVC dělí aplikaci do třech logických částí, kterými jsou:

  • Model
  • View
  • Controller

Tyto části se pokusím popsat na následujícím příkladu, kde se záměrně vyhýbám konkrétní programátorské technologii a za pomocníka si beru Excel. Podívejte se na následující obrázek:

Excel s tabulkou a grafy

Model je v tomto případě datová struktura, která drží čísla 105, 80 a tak dále. V aplikaci může být realizována jako pole čísel nebo třeba pomocí třídy s názvem Profit, konkrétní realizace není na této úrovni podstatná. Rovněž si všimněte, že příklad obsahuje průměr – tento výpočet rovněž logicky patří do modelu. Model jsou tedy data plus business logika (někdy zvaná doménová logika) aplikace. Teoreticky může být model pouhou sadou datových objektů bez business logiky, ale to je poměrně netypické.

View najdeme v příkladu hned několik. Určitě byste nepřešli bez povšimnutí čtyři různé grafy prezentující stejná data, ale i ona tabulka s čísly sama o sobě je dalším pohledem (View) – mohl bych tomuto pohledu například nastavit, aby čísla zobrazoval se znakem měny a podobně. View je tedy zobrazením modelu a dalších prvků uživatelského rozhraní (například záhlaví „Průměr“ žije čistě ve View a nemusí mít s Modelem nic společného).

Controller je nejhůře představitelnou částí na uvedeném příkladu. Projeví se ve chvíli, kdy upravím nějakou buňku. Controller má v tu chvíli na starost, aby se aktualizoval model, došlo k výpočtu nového průměru a překreslily se všechny View (pozor, to, jak se změny v Modelu projeví ve View, nemusí mít s Controllerem vůbec nic společného, Controller pouze tento proces spouští). Controller je tedy jakousi ústřední výkonnou jednotkou, která se stará o celkové provázání funkčnosti aplikace. Jak asi cítíte z této vágní definice, u Controlleru je poměrně velký prostor pro jeho upřesnění v jednotlivých variacích. Je tomu skutečně tak – právě pojetím Controlleru se jednotlivé vzory od sebe nejvíce liší, ale o tom až příště.

Návaznost jednotlivých komponent ilustruje následující obrázek:

Schéma základních vztahů v MVC

Jak naznačují šipky, v architektuře MVC v principu existují pouze dvě přímé vazby:

  • Controller má přímý odkaz na Model, aby mohl upravit jeho data
  • View má přímý odkaz na Model, aby mohl jeho data zobrazit

Všimněte si, že to je vše. Žádné další vazby nejsou na této úrovni podstatné, ačkoliv v praxi a v závislosti na konkrétní variaci MVC je ještě poměrně častá vazba mezi Controllerem a View (někdy jednosměrná, někdy obousměrná).

Co naopak nikdy nesmí existovat, je přímá vazba Modelu na ostatní dvě komponenty. V některých schématech uvidíte „nepřímou vazbu“ z Modelu na View, čímž se má na mysli, že když se data Modelu změní, příslušná View jsou upozorněna nějakým notifikačním mechanismem (např. pomocí vzoru Observer). V žádném případě však Model nemůže držet přímý odkaz na View nebo na Controller – to by byla hrubá chyba v návrhu aplikace.

Interakce s uživatelem

Jak do architektury MVC zapadá komunikace s uživatelem? Podívejte se na následující schéma:

Schéma interakce MVC s uživatelem

Výstup aplikace má vždy na starost View, ale složitější je to s uživatelským vstupem. Zde existují dvě principiálně odlišné možnosti:

  • U „widgetových“ systémů (komponentové frameworky typu Java Swing, Windows Forms, WPF, Silverlight, Flex, ASP.NET Web Forms, PRADO v PHP a podobně) umí uživatelský vstup ošetřit komponenty samy – například tlačítko umí reagovat na událost Click, textové pole dokáže zachytávat, co uživatel píše na klávesnici a podobně. Zde tedy uživatelský vstup primárně zachycuje View.
  • Pak máme systémy „newidgetového“ typu, kde žádné komponenty neexistují a ošetření uživatelského vstupu je tak potřeba učinit někde jinde. V příštím díle se podíváme, jaké konkrétně tyto systémy jsou, ale pro teď stačí říct, že v tom případě je to Controller, kdo zpracovává uživatelský vstup.

Zpracování uživatelského vstupu je pro dělení prezentačních vzorů hodně důležité, ale i o tom až příště.

Pár poznámek k Modelu

Ačkoliv MVC jako celek řeší prezentační vrstvu aplikace, pouze dvě komponenty mají přímo na starost prezentační funkcionalitu – jsou to View a Controller. Toto jsou také komponenty, které se v jednotlivých variacích liší, zatímco Model je stále stejný, a proto k němu můžu uvést pár poznámek už tady:

  • Nejčastější chybou začátečníků je, že za Modelem vidí pouze sadu datových objektů (možná proto, že v data-centrickém programování se „datový model“ skutečně orientuje primárně na datové struktury). Model ve smyslu MVC je však daleko víc, je to tzv. doménový model, který modeluje vztahy reálného světa. V něm jsou kromě dat důležité i další věci, jako například business pravidla („zákazník může otevřít novou objednávku až po zaplacení minulé faktury“) nebo validační pravidla („jméno je povinná položka“). Některé technologie svádí k definici doménových pravidel ve View (např. validátory v ASP.NET nebo ve Flexu), v architektuře MVC však správně patří do Modelu. Důvod je ten, že jednotlivá pravidla typicky potřebujeme ve více pohledech současně (např. při vytvoření nového zákazníka a pak při jeho editaci), a jejich uložení ve View by znamenalo nutnost duplikace. Proto se tento ochuzený model považuje za architektonickou chybu a Fowler ho řadí mezi antivzory pod názvem anemický doménový model.
  • O Modelu se většinou mluví v jednotném čísle, i když je obvykle realizován více objekty.
  • V klasickém třívrstvém modelu, kde máme datovou, aplikační a prezentační vrstvu, Model v prezentační vrstvě v principu odpovídá modelu v aplikační vrstvě. Bohužel není zcela obvyklé, aby nástroje uměly tyto modely synchronizovat – tento úkol je tak většinou na bedrech programátora.

Pokračování příště

Po dnešku máte dobrou představu o základní architektuře MVC, o základních vazbách mezi jednotlivými komponentami a o významu vrstvy zvané Model. Příště se podíváme na konkrétní variace MVC, kde to teprve všechno začne být zajímavé.

Používáte MVC?

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 59

Přehled komentářů

danaketh RE: Úvod do architektury MVC
psonek Pravidla
Lojza Re: Pravidla
ava Re: Pravidla
smilelover Re: Pravidla
ava Re: Pravidla
smilelover Re: Pravidla
ava Re: Pravidla
smilelover Re: Pravidla
Finta Re: Pravidla
Sten Re: Pravidla
Borek Bernard Re: Pravidla
dc web app
danaketh Re: web app
Borek Bernard Re: web app
Anonymní Re: web app
Borek Bernard Re: web app
Yenya Mezivrstvy jsou zlo
Sten Re: Mezivrstvy jsou zlo
Borek Bernard Re: Mezivrstvy jsou zlo
Sten Re: Mezivrstvy jsou zlo
Sten Re: Mezivrstvy jsou zlo
Borek Bernard Re: Mezivrstvy jsou zlo
Yenya Re: Mezivrstvy jsou zlo
Sten Re: Mezivrstvy jsou zlo
Borek Bernard Re: Mezivrstvy jsou zlo
Borek Bernard Re: Mezivrstvy jsou zlo
Víko Re: Mezivrstvy jsou zlo
YF Re: Mezivrstvy jsou zlo
Anonymní Re: Mezivrstvy jsou zlo
Borek Bernard Re: Mezivrstvy jsou zlo
Yenya Re: Mezivrstvy jsou zlo
v6ak Validace nejen do Modelu
ava Re: Validace nejen do Modelu
Borek Bernard Re: Validace nejen do Modelu
v6ak Re: Validace nejen do Modelu
dave Re: Validace nejen do Modelu
David Grudl RE: Úvod do architektury MVC
Borek Bernard RE: Úvod do architektury MVC
jos RE: Úvod do architektury MVC
Borek Bernard RE: Úvod do architektury MVC
jos RE: Úvod do architektury MVC
T Par poznamok
Borek Bernard Re: Par poznamok
T Re: Par poznamok
Borek Bernard Re: Par poznamok
T Re: Par poznamok
Anonymní Re: Par poznamok
YF nic moc :(
Borek Bernard Re: nic moc :(
YF Re: nic moc :(
Borek Bernard Re: nic moc :(
YF Re: nic moc :(
weeto Re: nic moc :(
Borek Bernard Re: nic moc :(
Marián Košťál Typy frameworkov
Borek Bernard Re: Typy frameworkov
ee CHYBA
Martin Hassman Re: CHYBA čtenáře
Zdroj: https://www.zdrojak.cz/?p=3004