Komentáře k článku
Ú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.
RE: Úvod do architektury MVC
Super. Tohle je přesně to co jsem potřeboval k ujasnění některých vazeb v MVC. Těším se na další díly.
Pravidla
Z teoretické stránky se v MVC zas tak moc neorientuju, ale prakticky bych řekl, že umím napsat MVC aplikaci. Tohle jsou moje pravidla:
Ze začátku je potřeba odolat pokušení měnit model přímo z view. A pak asi nejtěžší je navrhnout View interface. Buď je možnost si ho dobře promyslet předem nebo ho dělat stylem ad-hoc (postupně přidávat a měnit funkce).
Typický příklad editace osoby:
Re: Pravidla
Jo jo, moc se mi líbí, že ui event 'validace adres' je okoučováno v Controller::setAddress. :-))
Re: Pravidla
Hmm, prijde mi (i kdyz neznam kontext, pouzity jazyk ani framework :-), ze cely uvedeny priklad je tak komplikovany pouze proto, ze v sobe zahrnuje validaci – kontrolu toho, zda adresa neni prazdna, a pripadne osetreni. Kdyby mohla byt adresa libovolna, tak by mel priklad 0 radku, jestli to chapu spravne? (predpokladam ze samotne navazani view a controlleru na model tak, aby bylo mozne ve vstupnim policku editovat adresu, je v tomto priklade provedeno jinde, napr. v GUI builderu).
Potom podle me doslo presne k te chybe, na kterou je upozorneno i v clanku – validacni logika neni v modelu, ale ve view/controller.
Kdysi jsem psal mirne rozsahlou GUI aplikaci v pythonu (>100 oken), udelal jsem si vlastni MVC miniframework, ktery toto resil tak, ze kazdy model mel validacni metodu, ktera vracela kolekci aspektu ktere neprosly validaci, a popisu prislusnych chyb. Dialog potom pred acceptnutim volal funkci validate, ktera provedla validaci modelu, nasla k prislusnym nevalidnim aspektum prislusna views, ty vycervenila a prvni z nich focusla (aby uzivatel mohl pohodlne opravit chyby), a zobrazila errorbox se seznamem chyb v dialogu. Timto zpusobem byla oddelena prezentace chyb od samotne validace, veskera validace byla v modelu (bylo mozno zjistit zda je korektni i bez GUI), a do view/controlleru jsem nemusel nic cpat. Prislo mi to jako dobre reseni.
Omlouvam se za priserne vmixovavani cechoanglismu do prispevku :)
Re: Pravidla
Pozor! V clanku se pise, ze validacni pravidla maji byt vylucne v modelu, ne logika. Snazit se do modelu cpat i veskerou validacni logiku je casto drbani se levou rukou za pravym uchem.
U webovych aplikaci se regulerne a spravne resi validace na urovni C ci V, problem je, kdyz i ta pravidla jsou na techto vrstvach definovana a ony si je nezadaji od M (jako treba delky poli ci regexpy natvrdo zapsane primo v JavaScriptech pro validaci pred odeslanim formu).
Re: Pravidla
Hmm, neznam presnou definici 'validacni logiky' ani 'validacnich pravidel', tak se omlouvam za pripadne zmateni. Mel jsem na mysli 'programovy kod, ktery se vykona a overi, zda je model validni ci ne, a pokud neni, dokaze podat (nikoliv prezentovat) informaci o tom, co je spatne'.
V klasicke newebove aplikaci neni problem toto mit pouze v modelu. Jestli to chapu spravne, ve webovych aplikacich to problem byt muze, protoze model a jeho logika jsou ulozeny na serveru a odezva (pripadne pruchodnost site) by byly neumerne vysoke (je tu jeste jiny principialni problem? O webovych aplikacich moc nevim)
Asi nejcistsi reseni by bylo v takovem pripade bylo automaticky generovat javascriptovy client-side validacni kod ze zdrojaku validacniho kodu v modelu, aby se programator vyhnul duplicitam, ale nevim jestli to nekdo tak dela :) Pokud me nekdo pouci o tom, jak se toto dilema (duplikace kodu vs. odezva/propustnost) dnes resi, a jak by se spravne resit melo, budu jen rad..
Re: Pravidla
No, a ten kod k tomu overeni pouziva nejaka pravidla. Ta musi byt ulozena v Modelu, resp. presneji receno, Model o ne musime zadat. Ta logika muze byt IMHO kdekoliv a taky casto byva, protoze tlacit ji vzdy do modelu neni prakticke.
Ne, na serveru to klidne muze byt, ale treba v Controlleru, ne nutne v Modelu. I kdyz, kdyz se to tak vezme — validacni logika bude mit vzdy nejaky opakujici se kus kodu, takze nebude primo v controlleru, ale v nejakem validacnim manazerovi, ktery budou jednotlive controllery volat. A to uz je v podstate v Modelu.
Ale prikladem je treba validace pomoci anotaci na properties v controlleru (tam zas ovsem neni vzdy jednoduche rozumne ta pravidla dostat, alespon z pohledu Javy a jejiho chovani v pripade anotaci).
Priznam se, ze taky ne vzdy, ale vidim to jako idealni reseni. Vykonovym problemum se da vyhnout tak, ze se to negeneruje on the fly, ale pri deployi nejakym skriptem (Maven, Ant, Phing… moznosti je plno).
Re: Pravidla
ad. 1)
Nechapu vyznam pravidel, z meho pohledu kod = pravidla, o nic nezadam, proste spustim validacni metodu ktera je (a mela by) byt ulozena v modelu. U GUI aplikaci nevidim duvod, proc by to nemelo byt prakticke, krome spatne navrzeneho frameworku. Ponechme ted prosim stranou (opravdu, prosim, nebylo by to prinosem) napr. ulozene procedury v relacnich DB ktere kontroluji jeji konzistenci
ad. 2)
Proc by mela mit opakujici se kus kodu? Nevidim duvod, v mnou vyse zminene aplikaci se nic takoveho nestalo (pokud ano, bylo to mym opomenutim, nikoliv z principialniho donuceni)
DialogController v mem pripade delal pouze to, ze kdyz se uzivatel pokusil acceptnout dialog, tak provedl neco nasledujiciho (jde o myslenku):
validationResult = model.validate()
if not validationResult.isValid:
….self.highlightAndFocusInvalidWidgetsFrom(validationResult)
….self.showError(validationResult.errorText())
else:
….self.accept()
od te doby jsem NIKDY nemusel psat validaci nikam jinam nez do prislusnych model.validate(), a zadarmo jsem mel upozornovani uzivatele na chybna policka atp..
O validaci pomoci anotaci na properties v controlleru v Jave totalne nic nevim, ale nezni to moc lakave :-)
ad 3)
Problemem samozrejme neni vykon, ale
a) obtiznost prekladu z jednoho jazyka do druheho (ten mensi, i kdyz dost velky problem)
b) server muze napriklad validaci provadet oproti DB, coz javascriptovy klient nemusi mit umozneno. Pravidla na serveru a klientu by pak nebyla stejna, na klientu by zrejme byla jen nejaka oklestena verze serverovych. Toto rozliseni je snad jeste neprijemnejsi nez a)
Re: Pravidla
ad 1) Validace se temer vzdy da rozdelit na logiku a pravidla. Delky retezcu, hranice cisel, cisla vyhovujici rovnicim, regularni vyrazy. A jestli se tato pravidla pak pouziji v JS nebo treba v PHP, to uz je fuk.
ad 2) opakovani kodu jsem myslel prave to, ze kdyz rozdelime validaci na pravidla a kod validujici data podle pravidel, bude ten kod pro velky pocet pripadu naprosto stejny.
Validace pomoci anotaci v Jave je naopak velmi navykova :-) Jen je problem, ze hodnota property anotace nemuze byt treba vysledek volani staticke metody, ani kdyz ma RetentionPolicy.RUNTIME.
ad 3) jo, tak pokud jde o pravidla slozitejsi nebo vazana na existujici data, tak je lepsi se na validaci na klientovi uplne vykaslat. Je to zbytecny luxus.
Re: Pravidla
Z hladiska bezpecnosti je potrebne aby sa data validovali na strane servera. Validacia na strane klienta moze byt riesena cez Ajax. Tym sa da pekne vyhnut duplicite validacneho kodu a uzivatel dostane privetive prostredie. V pripade vypnuteho JS sa formular zvaliduje iba na strane servera.
Re: Pravidla
Ještě lepší je nedělat explicitní obsluhu vůbec, ale svěřit problém signálům a slotům (aka událostem a delegátům) a napojit je při tvorbě View.
Nejenom View, ale i Model by měl být interface. Potom můžeme dávat data na různá místa se stále stejnými View a Controllerem.
Re: Pravidla
Přesně podobná pravidla jsou mnohdy užitečnější, než nějaké malůvky a obecné popisy :) Nicméně, ve vašem příkladu validace probíhá v Controlleru, což je komponenta s prezentační a aplikační logikou, zatímco validace správně patří do doménového modelu. Takže i obecné poučky mohou být někdy užitečné :)
Také to, čemu říkáte Controller, je ve skutečnosti Presenter. Rozdíl mezi nimi bude vysvětlen v příštím díle.
Díky za dlouhý a dobrý komentář.
web app
pretoze vecsina web app/jazykov/platforiem zo zaciatku neobsahovali ziaden framework tak sa znovu objavuje koleso a sme uneseny ze nieco take existuje.Nechcem tym nikoho zhadzovat alebo celu teoriu MVC odpisovat, len mi to pride trochu zvratene.Mam pocit ako keby velka cast web vyvojarov proste zacala rovno z webom a nikdy do incoho ineho ani nepichla a preto su z toho taky uneseny, pritom pri beznych desktopovych aplikaciach toto su v podstate bezne veci.Napriklad take MFC funguje vlastne ako MVC framework (da sa na to aj tak pozerat).
Re: web app
Ono to tak ale často skutečně je. Já sice začal na Basicu a Pascalu ale v té době by mi MVC jen komplikovalo život. Teď si od toho webového patlání odskakuji k Pythonu (a občas naťuknu Ruby) a tak MVC a další možnosti poznávám až takhle pozdě.
Re: web app
Na MFC se dá dívat jako na MVC framework tak maximálně, když to necháte vyslovit Němce :)
Moje zkušenost je přesně opačná: udělat aplikaci s kvalitní MVC architekturou je na desktopu daleko náročnější než na webu. Je to patrně proto, že webový request-response model je jednoduchý a přímočarý – na začátku načtete data, ty nějak zpracujete, zkonvertujete do HTML nebo jiného výstupního formátu a tím máte hotovo. V aplikaci běžící na desktopu naopak pracujete se stavovým modelem, kde vám události od uživatele nebo od systému mohou přicházet z různých směrů a v různém pořadí, MVC triád existuje v každém okamžiku mnoho a podobně.
Jistě, MVC zde již máme desítky let, ale to ještě neznamená, že ho umíme správně používat. Toto bohužel platí jak pro web, tak pro desktop.
Re: web app
Tiez mi pride, ze architektura dokument/pohlad v MFC je velmi podobna v clanku opisovanemu MVC. Nie som vsak ziadny odbornik, ale potesilo by ma keby ste mohli, hoci velmi strucne, ukazat v com su si odlisne.
Re: web app
D/V nerozlišuje View a Controller, čímž se od MVC dost liší. Někde jsem četl, že při vývoji MFC se vzor MVC zvažoval, ale technologicky prý bylo těžké ho realizovat, proto tým radši zvolil D/V. Ale není to úplně moje teritorium, takže po mně víc nechtějte :)
Mezivrstvy jsou zlo
Nejprve: diky za clanek, tesim se na dalsi pokracovani. Treba mi mnohe osvetli.
Na druhe strane: je striktni rozdelovani na M, V a C vubec k necemu? Neni jednodussi proste podle potreby pouze refaktorizovat kod (ve stylu "kdyz uz neco delam podruhe/potreti, udelam si na to funkci/objekt/modul"?). Proc to striktne oddelovat? Chapu ze ma smysl oddelovat velkou cast View nekde bokem (uz proto, ze grafickou stranku veci casto navrhuje grafik/webdesigner, coz je nekdo jiny nez programator), ale duvod oddeleni M a C prilis nechapu, zvlast kdyz oboji pise ta stejna skupina lidi.
Ja jsem zatim ziskal pocit, ze MVC jen vytvari taaakhle tluste mezivrstvy, ktere v podstate nic nedelaji.
Videl jsem ne uplne maly (ale asi ne uplne velky) projekt v Ruby on Rails, kde se autor snazil dodrzovat MVC metodologii. Zhruba tretina az polovina kodu bylo zpristupnovani dat z SQL databaze do Ruby objektu (nepochybne znacna cast z toho mohla byt generovana), o neco mene bylo generovani HTML stranek, a uplne nejmene zrejme ten Controller. Akoratze vetsina toho kodu ve vsech trech vrstvach byly triviality typu "vezmu tento objekt/tento SELECT a toto z neho vypisu/vratim". Cili strasne moc textu ktery jen obaloval vrstvy do dalsich vrstev. Bylo tam zoufale malo mist, kde ten kod opravdu neco s daty delal. A kdyz clovek ukazal na stranku a chtel vedet proc je tam tato hodnota nebo co se stane kdyz stisknu toto tlacitko, bylo treba duvod hledat rozstrkany po nekolika oddelenych souborech zdrojoveho kodu.
Neni lepsi napriklad zapouzdrovat SELECT do neceho vetsiho az v pripade, kdy opravdu tentyz SELECT potrebuju vickrat? Tyhlety pokusy o zapouzdreni databaze do objektu vedou pak k tomu, ze nevyuzivam moznosti databaze (abych slozitejsim SELECTem nechal databazi spocitat to co fakt v tomto konkretnim pripade potrebuju), ale pouzivam DB jen jako neinteligentni uloziste, a pak az ex post si z objektu vybiram, co potrebuju.
Diky za pripadnou reakci na vyse uvedene treba v nekterem dalsim dile serialu.
-Yenya, http://www.fi.muni.cz/~kas/blog/
Re: Mezivrstvy jsou zlo
Důvod oddělení Modelu od Controlleru je kvůli tomu, že Model jsou opravdu jen nějak získaná data, která nemají sama nic dělat. Může to být třeba tenká vrstva nad databází, která bude vybírat data, jak o ně bude Controller (nebo View) žádat, nebo naopak úplně stejné View i Controller můžeme použít v embedded aplikaci, kde Model bude ukládat data do souboru a při startu je načte do paměti. Rozdíl je v tom, že nemusíme sahat do View ani Controlleru, tzn. nemusíme je ani znovu testovat. Stejně tak, pokud někdo přidá nové View a upraví Controller (nebo přidá nový; jeden Model může mít i více Controllerů), tak ho můžeme rovnou použít v obou verzích aplikace.
V test-driven development se naopak běžně nahrazuje Model za pevně daná data a zkouší se, jestli Controller reaguje správně (mění správná data) či View vykresluje to, co požadujeme. Stejně tak můžeme nahradit Controller za něco pevně daného a zkoušet Model. Díky tomu se testují jednotlivé části samostatně, což zjednodušuje ladění i optimalizace a také umožňuje lépe rozdělit práci v týmu (můžete vyvíjet Controller, i když nemáte Model, stačí mít příslušné testy).
Pokud Model jako obal databáze neumožňuje udělat složitější SELECT, který Controller nebo View potřebuje, bude nejspíš chyba v konkrétním Modelu.
Samozřejmě MVC se nehodí na všechny případy, u jednodušších aplikací je to zbytečně složitý koncept.
Re: Mezivrstvy jsou zlo
Nejsem si jistý, jestli odpovídáte úplně na to, co se snažil říct Yenya, nicméně mám k vašemu příspěvků jeden komentář.
Zdá se mi totiž, že mícháte Model a Servisní vrstvu. Pravda, máte nevýhodu, že je vám celý seriál servírován po kouskách a k popisu servisní vrstvy se dostaneme až ve třetím díle, nicméně na tomto místě bych rád podotknul, že dívat se na doménový model jako na (tenký) obal nad databází nebo jiným datovým úložištěm je nebezpečné. Model je naopak nosnou částí celé aplikace a je do značné míry na všem ostatním nezávislý – jak na prezentaci, tak na perzistenci.
Jak jsem říkal, servisní vrstvě je věnována kapitola ve třetím díle, takže tam snad vše bude vysvětleno lépe a podrobněji.
Re: Mezivrstvy jsou zlo
MVC docela běžně používám, takže o tomto vím. Ano, ve svém příspěvku jsem to dost zjednodušil, Model může být i hodně komplexní, může obalovat třeba nějaké košaté stromy nad kombinací databáze, souborů a RPC volání. Samozřejmě závisí to na tom, jestli berete Model jako abstraktní interface (potom je úplně nezávislý) nebo jako konkrétní implementaci (tak to beru já, nic o Servisní vrstvě nevím, protože o způsobu uložení dat MVC nic neříká).
Re: Mezivrstvy jsou zlo
Model jako abstraktní interface není úplně přesně. Nemyslím tím interface ve stylu Javy (tzn. nulová funkčnost), ale interface ve stylu C++ CRTP, kdy interface obsahuje validaci (a další logiku, která je společná pro všechny implementace příslušného Modelu), ale vše ostatní nechává na konkrétní implementaci.
Re: Mezivrstvy jsou zlo
Model je v MVC doménový model nezávisle na tom, jak definujete "interface". Mluvit o databázi je zavádějící, protože tu má na starost persistenční vrstva. A tu, jak správně poznamenáváte, MVC vůbec neřeší.
Re: Mezivrstvy jsou zlo
Ještě jinak: striktním vyžadováním těchto vrstev se obíráte o značnou škálu prostředků. Kam byste v MVC zařadil třeba triggery, uložené procedury v databázi, anebo třeba databázové zprávy (Oracle: dbms_alert)?
Nebo: lze pomocí MVC udělat aplikaci, ve které uživatel sám v podstatě skládá SELECT z nějakých dodaných prvků? Jako vývojář v zásadě víte nad jakými tabulkami tak ten SELECT může běžet, podle jakých sloupců se spojovat, podle jakých kritérií vybírat a třídit, a jak vypisovat data, ale to je tak všechno. Zbytek si určuje uživatel (příklad: různé statistické aplikace pro manažery – chtějí se na data dívat z fakt různých pohledů). Ne že by uživatel psal přímo SQL, ale v zásadě jeho podobu nějak určuje. Pokud toto není programovací nástroj převést na jeden velký SELECT, nevyužívá možností databáze a nemůže být optimální.
Nevím jestli tohle běžné MVC systémy umožňují (ale určitě je to layering violation, čemuž se snaží zabránit). A přitom je to v mnoha případech dost užitečné. Ne že by takto měl být psaný celý velký systém, ale je potřeba aby se ty mezivrstvy necpaly tam kde je explicitně nepotřebuju.
-Yenya, http://www.fi.muni.cz/~kas/blog/
Re: Mezivrstvy jsou zlo
Triggery patří do Modelu, stejně jako uložené procedury. Databázové zprávy by asi také patřily do Modelu (a Controller by si je vyzvedával), ale tam si nejsem jistý.
Pokud by se vhodně navrhl Model, tak by to šlo, ten SELECT by ale samozřejmě musel sestavit (a optimalizovat) on. Ale v tomhle případě by MVC asi bylo spíš na obtíž.
Re: Mezivrstvy jsou zlo
Přečtěte si, prosím, v článku ještě jednou, co je to Model. Triggery ani uložené procedury do něj rozhodně nepatří.
Re: Mezivrstvy jsou zlo
Triggery, uložené procedury a podobně nemají s MVC nic společného, jsou detailem persistenční vrstvy (v aplikaci zpřístupněné pomocí service layer).
Pro "uživatelské sestavení SELECT příkazu" lze použít například Specification pattern (najdete ji i pod mnoha jinými názvy).
Re: Mezivrstvy jsou zlo
Záleží na tom, co je v uložených procedurách implementováno. Rozhodně se nedá paušálně řící, že nemají s MVC nic společného.
Re: Mezivrstvy jsou zlo
MVC je architektonicky vzor primarne urceny pro systemy implementovane pomoci OOP – dal si nemyslim ze by vrstvy byly zlo :) obecne jsou vrstvy jenom jednou z mnoha forem dekompozice … MVC je rekl bych surovy zaklad vhodny pro systemy kde je jiz zapotrebi premyslet o napriklad rozsiritelnosti a nebo napriklad pokud mate tym lidi a projekt na kterem potrebujete resit rozdeleni prace – neni to dogma a jako vse se i toto da zneuzit nebo nespravne pouzit
Re: Mezivrstvy jsou zlo
Kontroler je uzitecny na hookovani kodu, oddeleni kontroleru a modelu se velmi hodi pro snadne testovani, ale i pro CLI utility pracujici s aplikaci. Rozhodne si nemyslim ze by ten pattern byl zbytecny :)
Re: Mezivrstvy jsou zlo
Díky za komentář, pokusím se reagovat.
> Je striktni rozdelovani na M, V a C vubec k necemu? (…) Chapu ze ma smysl oddelovat velkou cast View nekde bokem (uz proto, ze grafickou stranku veci casto navrhuje grafik/webdesigner, coz je nekdo jiny nez programator), ale duvod oddeleni M a C prilis nechapu, zvlast kdyz oboji pise ta stejna skupina lidi.
Oddělení zodpovědností do různých objektů je jedním ze základních principů dobrého objektového návrhu (tzv. Single Responsibility Principle). V případě MVC mají M a C dvě úplně jiné zodpovědnosti: Model obsahuje pouze data a doménovou logiku (tj. nemá s konkrétní prezentací nic společného), zatímco Controller je komponenta úzce spojená s prezentační a aplikační logikou.
Když jejich zodpovědnosti namícháte, stane se vám například, že Controller bude obsahovat doménovou logiku a tu budete muset duplikovat, když bude Controllerů víc. Zde mi asi namítnete, že v tu chvíli můžete doménovou logiku extrahovat do nějakého jiného objektu a že tím duplikaci zabráníte, ale víte co? V tu chvíli vytváříte doménový model, respektive jeho část! Jak vidíte, při kvalitním návrhu aplikace dodržujícím základní principy OOP se stejně k aplikaci s oddělenými vrstvami dopracujete, i když tomu třeba MVC říkat nebudete.
> A kdyz clovek ukazal na stranku a chtel vedet proc je tam tato hodnota nebo co se stane kdyz stisknu toto tlacitko, bylo treba duvod hledat rozstrkany po nekolika oddelenych souborech zdrojoveho kodu.
Tohle je typický problém mnoha architektur a vzorů. Nové vrstvy zvyšují úroveň abstrakce, což může být dobře i špatně. U komplikovanějších aplikací se většinou má za to, že se přidaná abstrakce vyplatí, ale neplatí to u všech aplikací.
> Tyhlety pokusy o zapouzdreni databaze do objektu vedou pak k tomu, ze nevyuzivam moznosti databaze (…), ale pouzivam DB jen jako neinteligentni uloziste, a pak az ex post si z objektu vybiram, co potrebuju.
To je otázka implementace, ne architektury MVC.
Díky,
B.
Re: Mezivrstvy jsou zlo
Když jejich zodpovědnosti namícháte, stane se vám například, že Controller bude obsahovat doménovou logiku a tu budete muset duplikovat, když bude Controllerů víc. Zde mi asi namítnete, že v tu chvíli můžete doménovou logiku extrahovat do nějakého jiného objektu a že tím duplikaci zabráníte, ale víte co? V tu chvíli vytváříte doménový model, respektive jeho část!
Samozřejmě, ale opravdu vytvářím jen část, a to přesně tu část, kterou tam mít musím (jinak bych duplikoval kód), a přesně v té chvíli, kdy ji začnu potřebovat. Ne dřív. Já netvrdím, že MVC-like architektura je obecně zlo, jen tvrdím, že mezivrstvy (raději ale volitelně použité helpery) by se neměly psát předčasně.
-Yenya
Validace nejen do Modelu
Řekněme, že mám nějaké políčko na sumu peněz. Bude to tedy desetinné číslo (třeba BigDecimal). Podmínky budou následující:
1) z definice vyplývá, že musí jít o číslo
2) z nějakého dalšího důvodu to musí být 200 – 500
Pravidlo č. 2 patří jednoznačně do modelu. Pravidlo č. 1 tam ale jednoznačně nepatří: model to dostává jako BigDecimal => ani se to k němu nemá jak dostat.
Re: Validace nejen do Modelu
Souhlas, 1) jsem povazoval za samozrejmost (patri s nejvyssi pravdepodobnosti do controlleru), mluvil jsem o validaci business logiky :)
Re: Validace nejen do Modelu
Když v Modelu napíšete něco jako
[Range(200, 500)]
var sum : BigDecimal;
máte v něm explicitně pravidlo, že proměnná je typu BigDecimal. Pokud model realizujete jako sadu netypových proměnných, rovněž v něm budete chtít nějak vyjádřit, že 'sum' je číslo.
Netvrdil bych proto, že pravidlo 1) do modelu "jednoznačně nepatří" – ono v něm naopak téměř vždy nějak zachyceno bude, i když ve většině technologií příslušnou "validaci" zajistí už kompilátor, případně interpret.
Jiná věc je potom vrstva View. Zřejmě vycházíte z předpokladu, že widget zachytávající vstup podporuje pouze String a tedy třeba v HTML můžu do políčka "suma peněz" klidně zadat "abc" (což je nevalidní). V tom případě ano, nějak potřebuji v prezentačních komponentách (V, C) zajistit, aby byl vstup v pořádku, nicméně taky si lze představit technologii, kde mám ovládací prvky typu TextInput, DecimalInput, DateInput atd., takže v obecné rovině nelze tvrdit, že validace ve View musí nutně existovat.
Re: Validace nejen do Modelu
Na tom, jestli jde o validaci v modelu, se shodneme, jen to říkáme jinak.
Samozřejmě, mohou tu být i omezené inputy, ale na nich to neukážu. A netvrdím, že to tam musí být, jen že za určitých podmínek můžu narazit na validaci mimo model. Prostě doufám, že se nenajde nikdo, kdo bude chtít třeba setMoney(String) /* první, co mě napadlo */ s validací čísla s tím, že veškeré validace mají být přece v Modelu.
Re: Validace nejen do Modelu
Tak jak to chápu já, tak v modelu musí být vždy všechna validační pravidla. To je jestli je implementuje i view je pak v podstatě jedno. Model je musí mít vždy.
Jak jinak by pak šlo snadno nahradit jeden view druhým? Např. webové rozhraní, klasickým UI nějakého lokálního klienta.
Takže v tomto případě, model si zkontroluje zda dostal bigdecimal a pak si zkontroluje jestli je mezi 200 a 500.
RE: Úvod do architektury MVC
Výborně napsané a hlavně jsem rád, že tenhle seriál vůbec vznikl.
RE: Úvod do architektury MVC
V podstatě jsi stál u jeho zrodu :) Jsem rád, že se líbí.
RE: Úvod do architektury MVC
Někomu se asi při četbě následujícího nebude zdát výskyt slova Struts. Jenže MVC je pořád stejná m*dka bez ohledu na jazyk, sebelepší implementace to nezmění.
Allen Holub: Holub on Patterns:
RE: Úvod do architektury MVC
I extrémní názory samozřejmě existují :)
RE: Úvod do architektury MVC
to není extrámní názor, to je oprávněná kritika ;) nikoliv však článku (i o špatnejch věcech se může psát, že), ale architektury MVC
Par poznamok
V prvom rade vdaka za clanok. Vdaka bubline okolo ASP.NET MVC sa dostava do popredia problematika MVC aj v (ASP).NET komunite. Casto chyba ale background, ktory tento clanok poskytuje
K uvodnej casti clanku nemam vyhrady, zial, ten zaver(posledny odsek) mi pride ako trosku zmotany, bud prilis vela nedotiahnutych myslienok na kope, alebo nedoslednost.
1. "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"
bohuzial, aj model moze byt ponaty rozne – aktivny(povedzme povodny koncept v duchu ktoreho su aj schemy v uvode clanku) a pasivny model, co ma potom zasadny dopad na riesenie controllera a view.
2. "Model ve smyslu MVC je však daleko víc, je to tzv. doménový model"
Model v zmysle MVC moze byt aj anemicky model(nechapat nutne ako urazku)(=transaction script pristup), active record, rozvinuty DDD model (ano, s domain modelom na vrchu), mozu to byt hoci vec services…od tohoto MVC ako pattern abstrahuje(vid. napr. GoF), nie je to vobec podstatne. (je tu vsak samozrejme otazka, ako riesit v kontexte konkretnej zvolenej architektury aktivny model, ak chceme ist touto cestou ;-)
"doménový model, který modeluje vztahy reálného světa"
bohuzial, toto je dost zavadzajuce zjednodusenie pointy DDD.
3. "např. validátory v ASP.NET nebo ve Flexu), v architektuře MVC však správně patří do Modelu."
Tu uz naozaj zachadzame do DDD. Nesuhlasim, zase nieco, co navrhovy vzor MVC neriesi.(vid. GoF)
Navyse, okolo tohoto je neuzavreta diskusia aj v ramci DDD sceny. Business rules ok, v idealnom pripade maju byt v domain vrstve, okolo toho je zhoda. Ale co so zakladnymi validaciami inputov (ktore maju mimochodom ambiciu riesit asp.net validatory?). Aby som mohol validovat v business vrstve, musim mat aspon vstupy v nejakej podobe, ktore jej dokazem posunut.
4. "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."
Prax ukazala, ze Views musia riesit aj otazku stavu GUI / document modelu / modelu prezentacnej vrstvy.(pocnuc SmallTalkom) a ze je z hladiska praxe rozumne uvazovat o dvoch veciach(co v pripade predhistorickych uvah o GUI bolo bezpredmetne). Z tohto faktu sa vyprofiloval Fowlerovsky MVP, ktory ponuka pekne riesenie/vychodisko.
Vid. materialy napr. na Fowlerovej stranke ku tejto problematike.
Re: Par poznamok
Hned na začátku díky za vynikající komentář. Pár poznámek:
– Pojem doménový model jsem použil, protože model reprezentuje problémovou doménu. Nemyslel jsem tím nutně model ve smyslu DDD, i když k této interpretaci tíhnu.
– V článku píšu, že model může být pouhou sadou datových objektů, ale že je to netypické. Netypické je to proto, že někam potřebujete dát validaci: ať už používáte doménový model ve smyslu DDD nebo třeba Active Record, validační pravidla vám kvůli principu DRY vždycky skončí v modelu. Pokud vaše aplikace validaci nepotřebuje, můžete si osekaný model dovolit, ale u drtivé většiny aplikací bude anemický model problémem. Proto jej taky Fowler řadí mezi ANTIvzory.
– "Modeluje vztahy reálného světa" je zjednodušením, ano. Pro úvodní článek o MVC snad postačuje.
– To, že GoF něco neřeší, ještě neznamená, že by se to řešit nemělo :) Řada jiných zdrojů naopak Model popisuje poměrně detailně, viz např. Fowler.
– Jednotlivé variace MVP jsou předmětem druhého dílu
– Mohl byste, prosím, rozvést pojem "pasivní model"?
Díky,
B.
Re: Par poznamok
Dakujem aj ja za reakciu. Myslim, ze nazorovo mame blizko(co ma tesi) a v podstate ide +- o hru so slovickami, netreba preto v mojich nasledujucich poznamkach hladat nutne oponovanie ;-)
– Fowler napr. v PoEAA popisuje rozne (enterprise) modely. DDD pristup sa hodi len na rozsiahle projekty s velmi zlozitym modelom, to zdoraznuje Fowler aj Evans(aj ked mnohe principy je mozne aplikovavat samozrejme na mensich). Netreba tento rozmer zbytocne vnasat do problematiky MVC, to je len nazor. Aj ked tomu oznaceniu dava Fowler v clanku, ktory sme citali asi obaja negativny nadych, v kontexte konktretneho projektu a jeho specifik(maly, CRUD oriented) by som to tak nevidel.
Pod anemickym ma na mysli predovsetkym odnatie behavior z domenovych objektov.
Ludia stavajuci napr. nad active record domenovy model v podstate nemaju, spliva s datovym modelom, alebo ho maju nad active recordom ako transaction scripty.
– Validacne pravidla / business rules, to sa zhodneme, patria do modelu, netreba to rozpitvavat.(ako z modelu passnut vysledky validacii a sprostredkovat ich pouzivatelovi, je temou na dlhe zimne vecery :-)
Otazne je, kam patria zakladne validacie user inputu(napr. datovy typ – date, int), aby bolo mozne vobec posunut input do domain modelu, upozornoval som na toto(a tusim aj iny citatelia vyssie)
Dalej je otazne ako riesit zobrazenie mandatory flagu pri inpute, ak povinnost vyplnit pole je zavisla od nejakeho business pravidla a pod.
ASP.NET validatory je mozne pouzit len na takuto zakladnu validaciu, hoci sa bezne pouziva aj na komplexne validacie ktore spadaju uz pod business.
(Dovolim si povedat, ze prave MVP dava na pekne odpovede na tieto problemy ovela viac priestoru)
– Modelovanie vztahov realneho sveta – ano, rozumiem, ta veta vo mne evokovala taku stratenu vetvu OOD, len som mal potrebu sa uistit – rozmyslam, ako to formulovat lepsie… ?? Domain model z hladiska DDD = vyber takej abstrakcie (takeho modelu), ktora najlepsie popisuje zakaznikov pohlad na svet(problemovu domenu), ktora je teda mysleniu zakaznika najblizsia. Je to podriadenie sa videniu sveta zakaznikom(resp. teami zakaznikovych domain expertov).
– MVC ma/nema riesit. MVC je pattern. Pattern je (overenou) odpovedou na urcity problem, ktory ma ambiciu riesit. To ako (konkretne) designovat model je predmetom inych patternov.(ktore rozobera ako bolo spomenute komplexne napr. Fowler). Uz takto je MVC v pozicii super patternu (niecoho co stavia na inych patternoch)
———-
– Aktivny model – vytvara notifikacie o zmenach, ktore sa v nom udiali. Views na tie, ktore su pre ne zaujimave pocuvaju, reaguju na ne tak, ze oslovia priamo model, ziskaju potrebne data a zobrazia ich/premietnu zmeny v modely na screen.
– Pasivny model napr. pri ASP.NET MVC. Model nevytvara notifikacie o tom, ze sa v nom nieco zmenilo. View sa musi o tom, ze sa ma prerenderovat dozvediet inak. Typicky tak, ze controller posle message(view potom priamo accessuje model) alebo(a to je menej stastne podla mna) ako je to v ASP.NET MVC, ze controller natlaci data(projekciu dat z modelu) do view a forcene jeho prerenderovanie a pod.
popisane namatkovo tu
http://www.phpwact.org/pattern/model_view_controller
Re: Par poznamok
Díky za vaše názory. Debatovat bychom jistě mohli i dále, ale to nejpodstatnější snad už zaznělo.
Mimochodem, nejste náhodou tento Tomáš: http://blog.aspnet.sk/tomas/default.aspx ? Jen tipuji :)
Re: Par poznamok
Je to tak ;-)
Re: Par poznamok
Rozumiem akurat "accessuje", "forcene" a "prerenderovanie". Zbytok je aky jazyk?
nic moc :(
neuveritelny jak se da z jednoduche myslenky vyrobit neco tak radoby sofistikovaneho – clanek mi spis pripada jako navod jak si postavit raketoplan nez popis vzoru – a to jeste autor slibuje pokracovani (ceho? :)) zda se mi ze se tu porad nekdo snazi prevykladat tu samou vec originalnim zpusobem ale uplne se zapomina na vlastni ucel toho co by vzor mel plnit …
spojovat jednotlive vrstvy pseudosemantikou v podobe car a rikat jim "(ne)prime vazby" atd. to mi prijde uz silna kava :) ale tak chybama se clovek uci … tak preju at to nejak de aspon kdyz uz nic :)
Re: nic moc :(
Tento článek popisuje architekturu MVC (pokud to není z nadpisu a z textu dostatečně jasné), vzory budou příště.
Re: nic moc :(
"architektura MVC" je proste blabol – MVC je vzor – relativne jednoducha myslenka (kterou architektura nejakym zpusobem zahrnuje) pojmenovavat architekturu podle vzoru a popisovat ji timto zpusobem zvlast je redundantni – pak to vypada jako raketoplan :) na architekturu je kladeno daleko vic pozadavku a MVC adresuje jen nektere z nich
Re: nic moc :(
Těším se na vaše komentáře ke třetímu dílu, kde se otázce, co to vlastně MVC je, krátce věnuji :)
Re: nic moc :(
kratce? :) no to uz bude na case! :))
Re: nic moc :(
A neměla by toto řešit hned první kapitola prvního článku?
Re: nic moc :(
Nejsem příznivcem dlouhých teoretických úvodů, proto je kapitola o terminologii tam, kde je. Většina čtenářů to snad ocenila / ocení.
Typy frameworkov
Prilis nesuhlasim s nazormi v odstavci "Motivace aneb problémy drag & drop vývoje". Myslim, ze je dolezite uvedomit si, cim sa odlisuju komponentove frameworky (ASP.NET WebForms) a poziadavkami riadene frameworky (ASP.NET MVC). Moj nazor je tu http://nmarian.blogspot.com/2009/01/porovnanie-aspnet-webforms-aspnet-mvc.html. Samotny vzor MVC je velmi stary (1979) v sucastnosti vsak jeho popularita rastie. Kazdy z typov webovych frameworkov v roznej miere naplna atributy kvality (udrziavatelnost, testovatelnost, znovupouzitelnost, ….) je to iba otazka volby pre co sa rozhodneme a ktore atributy kvality su pre nas dolezite. Prax myslim ukazala, ze takisto ako sa daju implementovat aplikacie pomocou komponentovych frameworkov, tak sa to da aj pomocou poziadavkami riadenych frameworkov.
Re: Typy frameworkov
Bude se vám líbit příští díl, který se přesně zabývá rozlišením komponentových a request/response modelů a tím, jaký dopad to má na použitelnou variaci MVC.
Díky za komentář!
CHYBA
ja nevim co programujete, ale ten diagram je totalne spatne!!!! model logicky musi ovlivnit view tedy vazba mezi modelem a view je nezbytna!!!!!
Re: CHYBA čtenáře
Já nevím, co komentujete, ale ten komentář je totálně špatně!!! Čtenář si musí napřed přečíst celý článek, aby ho správně pochopil a nedělal pak ze sebe v komentářích vola. Tato vazba dost důležitá. I v životě 8-)