MVC a 3-vrstvá architektura

Shampoo

MVC a 3-vrstvá architektura
« kdy: 23. 01. 2016, 22:58:15 »
Ahoj,

rád bych chtěl lépe pochopit jaký je vztah mezi 3-vrstvou architekturou a MVC/MVP architektonickým vzorem, jelikož mnoho lidí tyto dva termíny obvykle zaměňují (donedávna i já).

3-vrstvá architektura
Uplatnění převážně u aplikací typu klient/server (tedy např. webové aplikace). Každá vrstva typicky na jiné infrastruktuře.
  • Prezentační vrstva (UI, klient - PC uživatele)
  • Aplikační vrstva (výpočetní/hlavní jádro aplikace, webový server)
  • Datová vrstva (persistentní uložiště dat - databázový server)
Komunikace mezi jednotlivými vrstvami je lineární (1. vrstva komunikuje s 2. a 2. se 3. vrstvou).

MVC architektonický vzor
Rozdělen na 3 komponenty (nekomunikují lineárně), které jako celek řeší převážně prezentační vrstvu 3-vrstvé architektury.
  • View (generování UI)
  • Controller (stará se o vstup, upravuje model a říká, kdy se má View překreslit)
  • Model (datová a business část)

MVC tedy vůbec neřeší databázi (persistentní uložiště) jako takovou. View komunikuje s Modelem (read-only - pokud se data změní, View se překreslí, návrhový vzor observer).
MVP (Controller je v tomto případě Presenter) se liší tím, že View řeší jak generování UI, tak uživatelský vstup. View dle vstupu zavolá konkrétní Presenter, který už zajistí případnou změnu Modelu. Uživatel komunikuje tedy přímo s View.

Jestliže je tedy View komponenta, která na server straně generuje např. HTML, Model - business logika, tak nerozumím tomu, že MVC řeší Prezentační vrstvu 3-vrstvé architektury, jelikož jsou jednotlivé moduly na webovém serveru, tedy Aplikační (druhé) vrstvě a hlavně Model je jádro aplikace (je nezávislé) - zase Aplikační vrstva.

Buru rád za jakoukoliv radu/postřeh :-\





Kit

Re:MVC a 3-vrstvá architektura
« Odpověď #1 kdy: 23. 01. 2016, 23:21:08 »
Dalo by se říct, že MVC je jen dvouvrstvá architektura, protože klient komunikuje buď s View (zobrazení) nebo s Controllerem (modifikace). Tyto dvě vrstvy spolu nekomunikují, pouze si mohou předávat řízení - například přes formulář nebo HTTP 302.

Obě tyto vrstvy přímo komunikují s Modelem, ale zpravidla ani ten Model nekomunikuje přímo s databází, ale přes vrstvu Service. Opět to není lineární vazba, protože konfiguraci servisní vrstvy zajišťuje View či Controller.

Samotný Model se opět může skládat z více vrstev. Četl jsem i o pětivrstvém modelu, což už je na můj vkus poněkud příliš, ale někomu to může vyhovovat. Můj Model je jen jedna prťavá třída, protože pouze drží datové zdroje a přesměrovává řízení do servisní vrstvy, která obsahuje business logiku a má na starosti přímou komunikaci s databází. Opět může být rozdělena do více vrstev.

V reálu se tedy bavíme spíš o vícevrstvé architektuře než o konkrétním počtu vrstev. Při správné definici jednotlivých rozhraní je pak jednoduché aplikaci sestavit i udržovat.

Shampoo

Re:MVC a 3-vrstvá architektura
« Odpověď #2 kdy: 23. 01. 2016, 23:55:08 »
Ano, o servisní vrstvě vím, nicméně pořád nechápu to, že MVC je prezentační vrstva (což by měl být client side), případně tedy model na aplikační vrstvě...


Re:MVC a 3-vrstvá architektura
« Odpověď #3 kdy: 24. 01. 2016, 08:37:39 »
MVC a n-vrstvá architektura spolu vůbec nesouvisí. A 3-vrstvá architektura se nepoužívá u aplikací typu klient/server, protože aplikace typu klient/server jsou 2-vrstvá architektura. 3-vrstvá architektura má tři vrstvy – původně to byly vrstvy (tlustý) klient, aplikační server a databázový server. Dnes se ale často používá architektura s tenkým klientem, kde se logika tlustého klienta z části nebo úplně přesouvá na aplikační server. Případně z toho může vzniknout 4-vrstvá architektura, kde se aplikační server stará opravdu jen o aplikační logiku (jsou to nějaké služby, se kterými je možné komunikovat jen pomocí definovaného API) a přibyde prezentační server, který se stará o generování typicky HTML pro tenkého klienta.

MVC je pak způsob, jakým se řeší klient. V případě tlustého klienta je zcela na vrstvě klienta, v případě řešení s tenkým klientem se může použít tam, kde je logika klienta – pokud se použije tenký klient opravdu jen jako hloupý zobrazovač a veškerá logika klienta je na aplikačním serveru, bude MVC jedině na aplikačním serveru. Pokud je nějaká logika i na „tenkém“ klientovi, je logika klienta rozdělena mezi toho tenkého klienta a aplikační server a MVC pak může být na obou. Každopádně celé MVC je vždy na jedné vrstvě aplikace – i pokud budete mít logiku klienta částečně v tenkém klientovi a částečně na prezentačním (nebo aplikačním) serveru, a na obou stranách bude MVC, budou to dvě oddělená MVC, která spolu nějakým způsobem komunikují.

Ve vašem obrázku to máte špatně, protože model z MVC je součástí prezentační vrstvy a je to prezentační model – který může a nemusí mít stejnou strukturu, jako model na aplikační vrstvě. V klasické třívrstvé aplikaci můžete mít vedle sebe tři různé modely – na nejnižší vrstvě model relační databáze, na aplikační vrstvě doménový model (a mezi těmi dvěma modely překlápí typicky ORM), na prezentační vrstvě pak prezentační model (ten, který je součástí MVC).

Shampoo

Re:MVC a 3-vrstvá architektura
« Odpověď #4 kdy: 24. 01. 2016, 10:59:40 »
Myslel jsem, že typická webová aplikace se označuje za architekturu client-server. Ta se ale skládá z klienta, webového serveru a navíc databázového serveru, tedy 3vrstvá. Nebo tomu tak není? Proč?

Možná je to pořád tím, že si pod každou vrstvou představuju oddělený HW...
Nakreslil jsem obrázek webové aplikace (tenký klient). Chápu tedy, že může být současně MVC na klientovi (asi tedy nějaký JS MVC framework) a také na webovém serveru (např. MVP Nette framework), jedná se tedy stále o prezentační vrstvu... Nicméně nerozumím tomu, že Model v MVC/MVP je součástí prezentační vrstvy, když obsahuje business logiku...



Může prosím někdo opravit, případně zakreslit podobný obrázek jak je to u typické webové aplikace (např. s Nette/Symfony frameworkem)?


JmJ

  • ****
  • 303
    • Zobrazit profil
Re:MVC a 3-vrstvá architektura
« Odpověď #5 kdy: 24. 01. 2016, 11:07:50 »
Omlouvam se za temer neuzitecnou odpoved, spis takovou poznamku. Urcite je dobre mit o tehle vecech rozumny prehled, ale rozhodne si nemyslim, ze by bylo potreba uplne presne vedet, co kam presne patri atd. Kazda aplikace ma urcite mnozstvi vrstev, je dobre se je snazit drzet nejak samostatne, ale raketovou vedu bych v tom nehledal.

perceptron

Re:MVC a 3-vrstvá architektura
« Odpověď #6 kdy: 24. 01. 2016, 11:28:48 »
otazka je preco sa pytate: pisete diplomku?

lebo o detailoch mvc a vrstiev sa da hadat donekonecna.

napr.

Citace
Nicméně nerozumím tomu, že Model v MVC/MVP je součástí prezentační vrstvy, když obsahuje business logiku...
model nema obsahovat business logiku

java serverove veci (stare strutsy, spring mvc) maju v modeloch len blbe triedy ktore obsahuju len data nutne pre zobrazenie v gui

business logika je bud v kontroleroch (c v mvc) alebo dokonca v business vrstve


Kit

Re:MVC a 3-vrstvá architektura
« Odpověď #7 kdy: 24. 01. 2016, 12:25:22 »
model nema obsahovat business logiku
...
business logika je bud v kontroleroch (c v mvc) alebo dokonca v business vrstve

Business logika do kontroleru nepatří, protože kontroler nemá přístup k databázi, ve které je podstatná část business logiky. Kontroler pouze sbírá údaje od klienta a sestavuje modifikační požadavky pro model.

java serverove veci (stare strutsy, spring mvc) maju v modeloch len blbe triedy ktore obsahuju len data nutne pre zobrazenie v gui

Data do modelu také nepatří. Model si pouze drží datové zdroje, ale samotná data v něm nejsou.

Re:MVC a 3-vrstvá architektura
« Odpověď #8 kdy: 24. 01. 2016, 12:32:27 »
Myslel jsem, že typická webová aplikace se označuje za architekturu client-server. Ta se ale skládá z klienta, webového serveru a navíc databázového serveru, tedy 3vrstvá. Nebo tomu tak není? Proč?
Typické klient-server aplikace zažívaly svůj vrchol někdy před koncem tisíciletí, a byly to skutečně dvě vrstvy – klient byla třeba Windows aplikace napsaná v Delphi, která přes SQL přímo přistupovala do databáze (server). Webová aplikace určitě není typickou ukázkou architektury klient-server, protože tam těch klientů a serverů máte obvykle několik (webový server obvykle bude klientem aplikačního serveru nebo databáze). Můžete webové aplikaci samozřejmě také říkat klient-server architektura, protože tam nějaké servery a nějací klienti jsou, a abyste to odlišil od monolitické aplikace. Ale je podle mne méně matoucí držet se zažitého používání pojmů a označovat webové aplikace za vícevrstvé.



Možná je to pořád tím, že si pod každou vrstvou představuju oddělený HW...
Což je dobrá představa a myslím, že je to jednodušší pro pochopení. To, že si pak někdo nacpe webový server a databázi na jedno železo, je speciální případ. Ale když si představíte, že máte na jednom počítači webový prohlížeč, ten komunikuje s webovým serverem, který generuje HTML kód, webový server komunikuje s aplikačním serverem, kde je aplikační logika (poskytovaná přes nějaké API), a aplikační server komunikuje s databázovým serverem, máte tam krásně i hardwarově oddělené čtyři vrstvy.

Nakreslil jsem obrázek webové aplikace (tenký klient). Chápu tedy, že může být současně MVC na klientovi (asi tedy nějaký JS MVC framework) a také na webovém serveru (např. MVP Nette framework), jedná se tedy stále o prezentační vrstvu...
Ano, u čtyřvrstvé architektury, kde je tenký klient a prezentační server je oddělený od aplikačního, je prezentační logika často rozdělená mezi prezentační server a tenkého klienta. Případně může být opravdu tenký klient úplně bez logiky – to jsou klasické webové formuláře, kde něco vyplníte, odešlete na server, tam se to zpracuje a server vytvoří HTML stránku s odpovědí. Je to sice architektonicky čisté, ale odezva na každou akci uživatele pak jde přes server, což je pomalé (projevuje se tam latence sítě).

Nicméně nerozumím tomu, že Model v MVC/MVP je součástí prezentační vrstvy, když obsahuje business logiku...
Model v MVC neobsahuje business logiku, obsahuje data pro prezentační vrstvu. U klasické formulářové webové aplikace je model v podstatě to, co se odešle typicky jako obsah POST požadavku na server (ze serveru do prohlížeče to jde typicky jako součást webové stránky, tam je tedy model a view pro přenos spojeno dohromady). Nebo pokud je to webová aplikace komunikující pomocí JSON zpráv, jsou modelem ty JSON zprávy.

Když budete mít třeba webovou stránku zobrazující údaje o nějaké osobě, budete tam mít model, který bude obsahovat jméno, příjmení, datum narození, adresu. Bude obsahovat jen tahle data, logika tam nebude vůbec žádná. Případně v implementaci (nějaké PHP nebo Java třídy, ve skutečnosti jsou to ale jen struktury bez jakéhokoli výkonného kódu) tam třeba budou nějaké jednoduché validace, což je ale vlastně porušení těch klasických vrstev (protože „správně“ by validaci měla dělat až business logika na aplikačním serveru). Tenhle prezentační model se pak mezi prezentační a aplikační vrstvou překlopí na doménový model (pokud „náhodou“ nejsou stejné), a teprve nad doménovým modelem pracuje ta business logika (která třeba zkontroluje, zda daný uživatel má právu tuhle osobu editovat, ověří, že datum narození není v budoucnosti, zda nevzniká duplicitní záznam o osobě v databázi, normalizuje adresu apod.).

Zkusím to ještě popsat opačně, proč vzniklo MVC. Bez MVC můžete mít na formuláři tři políčka – pro rodné číslo, datum narození a pohlaví. Každé to formulářové políčko si pamatuje svou hodnotu, a pak musíte naprogramovat chování pro ta jednotlivá políčka. Když uživatel změní rodné číslo, zkontrolovat jeho formát, vypočítat datum narození a zapsat ho do příslušného políčka, vypočítat pohlaví a zapsat ho do příslušného políčka. Když uživatel změní datum narození a je vyplněno rodné číslo, zobrazit dotaz, že se pravděpodobně jedná o cizince bez rodného čísla, a zda chce rodné číslo vymazat. Pokud zvolí, že ne, vrátit datum narození na hodnotu vypočtenou z rodného čísla. Když ale vymažete rodné číslo, nesmíte zapomenout i vymazat pohlaví. A takhle se to postupně řetězí a při každé změně v nějaké komponentě na formuláři musíte myslet na to, co všechno to může ovlivnit jinde. Pak třeba k políčku pro zadání data narození přidáte tlačítko pro výběr z kalendáře, a musíte zajistit, aby se ty dva údaje synchronizovaly a při změnách v kalendáři se provádělo to samé, jako při změnách v textovém políčku. Postupně tak z toho vznikne dlouhý kód plný různých ifů, logika se tam duplikuje a za chvíli se to celé bude chovat zmateně (třeba když změníte dvě hodnoty v jednom pořadí, bude na nějakém třetím políčku výsledek jiný, než když je změníte v obráceném pořadí).

Proto vzniklo to MV, kde máte to zobrazení (view) a model oddělené. Prostě jenom řeknete, že v tomhle políčku je datum narození, a nemusíte v pohledu řešit, co se má stát při jeho změně a kdy se má naopak aktualizovat – protože o to se stará model. Samotné MV by pak stačilo pro jeden formulář, jenže typicky jich máte víc a potřebujete určit, že když aplikační logika zjistila, že je v datech něco špatně, má se zobrazit zase ten původní formulář se změněnými údaji a validační hláškou, ale když aplikační logika data zpracovala (a třeba uložila do databáze), má se uživateli zobrazit jiná stránka třeba s poděkováním za registraci. A to řeší C – controller.

V tom případě, který jsem popsal, je opravdu část té business logiky (jaký je vztah mezi rodným číslem, datem narození a pohlavím) vytažena až k tomu modelu v MVC, ale to neznamená, že je to architektonicky součástí modelu. Architektonicky čisté by bylo vzít ten model z prezentační vrstvy, odeslat ho na aplikační server, tam třeba z toho rodného čísla vypočítat datum narození a pohlaví a odeslat to zpátky na klienta. Jenže za to vám uživatel nepoděkuje, když na to bude muset čekat a za tu dobu by to datum narození napsal sám.
« Poslední změna: 24. 01. 2016, 17:22:02 od Roman Bořánek »

Zelenáč

Re:MVC a 3-vrstvá architektura
« Odpověď #9 kdy: 24. 01. 2016, 13:28:50 »
Když děláš v javě nebo v .NET s formy, tak tam máš v souboru (nebo je to skytě vygenerováno) zvlášť vykreslení formuláře (kde je umístěno tlačítko, jak bude formulář velký, jaké rozložení tam uvnitř bude) a zvlášť přiděluješ jednotlivým událostem, vzniklým ve formuláři, reakci. Tohle rozdělení mi příjde jasné, je to pro pořádek. Označil bych to jako View-Controler. No a někdy je dobré tam dát ještě vrstvu představující model, a to může být třeba nějaká jednoduchá lokální databáze. Třeba aplikace umožňující nastavit několik alarmů, s různými tóny. Tady bych pro pořádek přidal i ten Model jakožto úložnu stavů té aplikace. Model, View i Controler bych umístil do samostaných souborů. Nicméně myslím si, že třeba takové vyskočení formuláře s aktivovaným alarmem bych řešil přes controller a nedělal bych pro to znovu další MVC. Účel světí prostředky.

No a třívrstvá architekura je v principu to samé, ale s velkým rozdílem v tom, že když se řekne tří vrstvá architektura, tak si pod tím představím pořádnou databázi, pořádný middle tier a pořádné klienty a mám to ve spojitosti s informačním systémem. Jinak ten princip rozdělení něčeho do tří samostaných vrstev mi přijde naprosto stejný jako MVC.

Shampoo

Re:MVC a 3-vrstvá architektura
« Odpověď #10 kdy: 24. 01. 2016, 13:45:48 »
model nema obsahovat business logiku
...
business logika je bud v kontroleroch (c v mvc) alebo dokonca v business vrstve

Business logika do kontroleru nepatří, protože kontroler nemá přístup k databázi, ve které je podstatná část business logiky. Kontroler pouze sbírá údaje od klienta a sestavuje modifikační požadavky pro model.

java serverove veci (stare strutsy, spring mvc) maju v modeloch len blbe triedy ktore obsahuju len data nutne pre zobrazenie v gui

Data do modelu také nepatří. Model si pouze drží datové zdroje, ale samotná data v něm nejsou.

V tomhle souhlasím s Kitem, protože pokud máme např. modelující třídu Auto, tak:

  • V databázi máme veškerá data (členské proměnné), nicméně ty nejsou v této třídě vůbec - je tam např. pro mapování na relační databázi, takže např. v tomto případě je model jako container
  • Tato modelující třída obsahuje metody, které říkají, jak se např. auto chová atp. - což je ta business logika, nebo?
Dále navíc zdroj: https://www.zdrojak.cz/clanky/uvod-do-architektury-mvc/, kde je několikrát zdůrazněno, že model obsahuje většinou i business logiku...
Data v modelu ale podle mě můžou být a to jak říká Filip Jirsák - např. je součástí modelu nějaký JSON, pole dat atp.

Když se podívám do mé obvyklé Nette aplikace, tak tomu opravdu tak je. V presenteru mám většinou jen nějaké reakce, na uživatele a případně nějaké rozhodnutí, jak postupovat v aplikaci dál - tedy aplikační logika?

Zelenáč

Re:MVC a 3-vrstvá architektura
« Odpověď #11 kdy: 24. 01. 2016, 13:47:59 »
Ale co mi není doteď jasné u MVC je tohle:

Chci udělat form, který bude něco dělat. Udělám proto třídu Formulář, definuji ji komponenty k vygenerování a definuji ji v nějakém initu jak se mají komponenty vygenerovat. Potom v metodách definuji reakce na události vzniklé ve formuláři a do atributů třídy je budu ukládat.

Potom: část která generuje vzhled je View. Metody které reagují na formulář jsou Controller a atributy třídy jsou Model. jinými slovy já moc nechápu smysl toho MVC, protože prostě každá formulářová třída s formulářem je ve své podstatě MVC, jen je to všechno v jediné třídě - a chtěl bych vidět situaci, kdy by kvůli toho vznikal nějaký chaos. Prostě, hlavně to musí být přehledné no :-)

Zareagujte na to někdo já vám dám schválně příklad, jak bych navrhl třeba Klienta u 3-vrstvé architektury bez použití nějakého striktiního mvc.

Kit

Re:MVC a 3-vrstvá architektura
« Odpověď #12 kdy: 24. 01. 2016, 14:16:43 »
Data do modelu také nepatří. Model si pouze drží datové zdroje, ale samotná data v něm nejsou.

  • V databázi máme veškerá data (členské proměnné), nicméně ty nejsou v této třídě vůbec - je tam např. pro mapování na relační databázi, takže např. v tomto případě je model jako container
  • Tato modelující třída obsahuje metody, které říkají, jak se např. auto chová atp. - což je ta business logika, nebo?

Data v modelu ale podle mě můžou být a to jak říká Filip Jirsák - např. je součástí modelu nějaký JSON, pole dat atp.

Pokud jsou data typu JSON či XML, která se načítají jako konfigurace, tak je mám ve formě samostatného objektu, ve kterém je definováno i chování. Model si pak drží pouze odkaz na tento servisní objekt ve formě jednoho privátního atributu a injektuje tento objekt do volání metod servisních tříd.

Chování objektu je možné označit za business logiku. Pokud někdo používá anemický model, pak tuto business logiku cpe do controlleru.

Pokud je chování uloženo v modelu, je tam velké riziko jeho nabobtnání do neúnosné (čti obtížně udržovatelné) velikosti a proto je dobré takový model rozdělit do více domén ve více vrstách.

Kit

Re:MVC a 3-vrstvá architektura
« Odpověď #13 kdy: 24. 01. 2016, 14:31:30 »
Chci udělat form, který bude něco dělat. Udělám proto třídu Formulář, definuji ji komponenty k vygenerování a definuji ji v nějakém initu jak se mají komponenty vygenerovat. Potom v metodách definuji reakce na události vzniklé ve formuláři a do atributů třídy je budu ukládat.

Potom: část která generuje vzhled je View. Metody které reagují na formulář jsou Controller a atributy třídy jsou Model. jinými slovy já moc nechápu smysl toho MVC, protože prostě každá formulářová třída s formulářem je ve své podstatě MVC, jen je to všechno v jediné třídě - a chtěl bych vidět situaci, kdy by kvůli toho vznikal nějaký chaos. Prostě, hlavně to musí být přehledné no :-)

Takový View mám v jedné třídě, reakci na takový formulář (Controller) v další třídě a výsledné chování (vliv na databázi) v další třídě - Modelu. Jsou to tedy tři samostatné třídy, které mají mezi sebou definováno komunikační rozhraní. Pro každý formulář mám samostatný View i Controller a pro každý typ formuláře i samostatnou servisní třídu v Modelu.

Ano, dá se to nacpat do jediné třídy, ale to se hodí jen pro primitivní úlohy na úrovni jedné tabulky v databázi.

Shampoo

Re:MVC a 3-vrstvá architektura
« Odpověď #14 kdy: 24. 01. 2016, 14:35:02 »
Ale co mi není doteď jasné u MVC je tohle:

Chci udělat form, který bude něco dělat. Udělám proto třídu Formulář, definuji ji komponenty k vygenerování a definuji ji v nějakém initu jak se mají komponenty vygenerovat. Potom v metodách definuji reakce na události vzniklé ve formuláři a do atributů třídy je budu ukládat.

Potom: část která generuje vzhled je View. Metody které reagují na formulář jsou Controller a atributy třídy jsou Model. jinými slovy já moc nechápu smysl toho MVC, protože prostě každá formulářová třída s formulářem je ve své podstatě MVC, jen je to všechno v jediné třídě - a chtěl bych vidět situaci, kdy by kvůli toho vznikal nějaký chaos. Prostě, hlavně to musí být přehledné no :-)

Zareagujte na to někdo já vám dám schválně příklad, jak bych navrhl třeba Klienta u 3-vrstvé architektury bez použití nějakého striktiního mvc.

No ale takto vytvoříš jednoúčelovou třídu - Formulář, který dělá jednu konkrétní věc. Když budeš chtít změnit funkčnost, tak musíš upravovat celou třídu.

Běžně bych řekl následující:
Model - Formulář má nějaké vlastnosti - kolik textboxů tam je (souřadnice), jednotlivá tlačítka atp. (zde může být např. obecná validace), data může Model získat např. z databáze, nebo nějakého souboru atp.)
View - Na základě Modelu vykreslím (vygeneruju HTML) formulář a dle konkrétní informace přiřadím akci
Presenter - Pokud uživatel klikne z View na tlačítko (je tam název akce, která se má vykonat), tak View řekne - hele, uživatel klikl na tlačítko a chce provést požadovanou akci - presenter najde akci a zavolá ji

Nicméně ty akce, které se s daty mají provést, vůbec v Modelu být nemusí (pokud se jedná o obecný formulář). Zavolá se nějaká metoda jiné Modelující třídy - data z formuláře se předají a dle toho se něco provede (business logika).

Lze tedy vyměnit View, aby se na základě Modelu vykresloval nějak jinak a při změně vlastností konkrétního formuláře (třeba změna volání akce jiné modelující třídy, nebo třeba úplně upravit validaci), tak zbytek neovlivní. Na funkčnost

Je to tak?