Alternativy k MVC a závěrečné poznámky

Zatímco předchozí dva díly byly zaměřené na architekturu a vzory z rodiny MVC, dnes se budeme věnovat „věcem okolo“. Především to budou alternativní prezentační vzory, podíváme se na úlohu servisní vrstvy a několika poznámkami celou minisérii uzavřeme.
Seriál: MVC a další prezentační vzory (3 díly)
- Úvod do architektury MVC 7. 5. 2009
- Prezentační vzory z rodiny MVC 11. 5. 2009
- Alternativy k MVC a závěrečné poznámky 15. 5. 2009
Alternativy k MVC
K architektuře MVC dnes existují dvě rozšířené alternativy:
- Autonomous View
- Presentation Model (jinak zvaný Model-View-ViewModel)
Autonomous View
Komponenta chovající se jako Autonomous View v sobě kombinuje uživatelské rozhraní a další logiku, ať už prezentační, aplikační, doménovou, nebo jejich mix. V PHP budiž příkladem skript, který na začátku načte data z MySQL databáze a pak je pomocí různých podmínek a cyklů vypíše do HTML. Ve widgetových systémech zase aplikace s Autonomous View často vznikají při „drag&drop vývoji“.
Samozřejmě, pokud jste sérii o MVC dočetli až sem, nemáte patrně o „vzor“ Autonomous View zájem nebo se od něj naopak snažíte oprostit, ale přesto za zmínku stojí, protože:
- Je zdaleka nejrozšířenějším modelem vývoje aplikací (podle Programátorovy statistické ročenky)
- Je výchozím modelem většiny technologií
- U malých aplikací nebo v jiných specifických případech může být praktičtější než MVC
Věnujte prosím pozornost poslednímu bodu: opravdu nemá cenu snažit se MVC aplikovat vždy a všude, příkladem budiž drobná prezentační logika na klientovi v lehkých AJAX aplikacích. Ale nebojte se, poslední větou, kterou si o Autonomous View přečtete, bude samozřejmě doporučení se mu pokud možno vyvarovat u jakékoliv netriviální aplikace – vyhnete se mnoha jeho problémům, mezi které patří obtížná až nemožná testovatelnost aplikace a téměř žádná dělba zodpovědností vedoucí k horší udržovatelnosti, menší flexibilitě a dalším nepěkným věcem.
Presentation Model (Model-View-ViewModel)
Vzor Presentation Model (PM), někdy nazývaný Model-View-ViewModel (M-V-VM), se obvykle zařazuje mimo MVC/MVP, nicméně i on patří mezi „dobré“ prezentační vzory, které se řídí podobnými principy jako MVC.
Vzor PM se většinou zobrazuje následovně:

Hlavní rozdíl je, že View již nepřistupuje k Modelu přímo, nýbrž přes mezivrstvu, kterou je prezentační model. Tato mezivrstva je dále zajímavá tím, že je jakousi kombinací Modelu a Presenteru.
Asi právě kvůli tomu se PM často popisuje jako vzor odlišný od MVP, nicméně zkusme se na diagram podívat jinak. V reálné aplikaci je úplně klidně možné, že komponenta prezentačního modelu bude realizována ne jedním, ale několika objekty, když např. budeme chtít oddělit chování a stav. Ve chvíli, kdy to uděláme, se diagram velmi přiblíží modelu MVP – chování bude uloženo v Presenteru a stav v Prezentačním Modelu. Protože zde PM implementuje návrhový vzor Adapter, někdy se mu říká Model Adapter, což je koncept z některých MVP implementací známý. Jak tedy vidíte, rozdíl mezi PM a MVP není tak velký, jak se může na první pohled zdát.
Servisní vrstva
Jestliže je MVC architekturou prezentační vrstvy aplikace, možná se ptáte, jak aplikace komunikuje s okolním světem. Musí přece nějak data do modelu načíst, ať už z lokálního disku nebo třeba z databáze. Často přece potřebuje komunikovat s nějakou webovou službou nebo něco na ten způsob. Kde tedy žije tato funkcionalita?
Umístit ji do modelu je možné, ale nešikovné. Například třída, která implementuje zákazníka a současně dokáže jeho data uložit na disk, porušuje Single Responsibility Principle. Odpovědí je tedy oddělení čtvrté části aplikace, které se říká servisní vrstva (Service Layer).
Servisní vrstva má s Modelem společné to, že nijak nesouvisí s konkrétní prezentací a byla by tedy chyba, kdyby se přímo odkazovala na objekty View nebo Controlleru. Pokud do diagramu MVC přidáme servisní vrstvu, bude vypadat následovně:

Tento model, někdy nazývaný „MVCS“, zachycuje kompletní architekturu aplikace, která dělá vše, co se od prezentační vrstvy očekává: umí data načíst, zobrazit, upravit a uložit.
U servisní vrstvy si všimněte pár věcí:
- Servisní vrstva může, ale nemusí mít přímou referenci na Model. Obvykle se taková reference považuje za přijatelnou, i když obecně platí, že čím volnější vazba mezi komponentami, tím lépe.
- Objekty servisní vrstvy jsou typicky schované za rozhraním, aby šel Controller testovat a nemusely se přitom používat reálné externí systémy, které mohou být pomalé nebo způsobovat jiné problémy. Pokud mám tedy např. v aplikaci službu EmailService, schovám ji za rozhraní IEmailService (nebo ještě lépe IMessagingService) a controlleru během testování předám FakeEmailService, která text jen uloží do souboru nebo třeba neudělá vůbec nic. Testování tohoto typu dále usnadňují tzv. mock frameworky, které se dají nalézt pro většinu dnešních technologií.
Poslední velká složitost MVC
Pokud jste pochopili základní principy MVC i rozdíly mezi jednotlivými variacemi, gratuluji, pravděpodobně nyní o MVC víte více než 95 % vašich vývojářských kolegů po celém světě (opět převzato z Programátorovy statistické ročenky; zmatení kolem MVC bohužel stále drtivě poráží jeho pochopení).
Přesto je ještě jedna věc, která stojí mezi vámi a dokonale napsanou aplikací: konkrétní technologie. Ono na diagramu se třemi obdélníčky a pár šipkami vypadá vše jednoduše, ale v reálu existuje v aplikaci „MVC triád“ hodně a zařídit, aby mezi sebou komunikovaly bez vytváření pevných závislostí, není vůbec jednoduché. Každá technologie má svůj vlastní „nejlepší způsob“, který bude záviset na věcech jako:
- jakým způsobem se načítá aplikace a instanciují objekty
- zda má technologie podporu pro data binding
- jestli jsou metody pro přístup k datům synchronní nebo asynchronní
a podobně. Co bude krásně fungovat v technologii A, nemusí být v technologii B vůbec použitelné nebo minimálně může existovat daleko lepší způsob. Klišé na tomto místě je, že kdo zná principy, snadno si poradí, ale toho jsem si v praxi bohužel nevšiml. Znovu se vrátím k tomu, co jsem psal už v prvním díle: znalost obecných architektonických principů je užitečná, ale ne vždy dá konkrétní odpovědi na otázky, které potřebuje vývojář znát. Chápat MVC v jeho principu a umět vytvořit kvalitní aplikaci v konkrétní technologii je asi podobné jako chápat, že na kytaru se hraje mačkáním strun a brnkáním, a pak umět zahrát Bacha.
MVC: vzor, architektura nebo princip?
Série o MVC by nebyla kompletní, kdybych se aspoň na chvíli nezastavil u toho, co to vlastně MVC je. Možná vám připadá zvláštní, že tato kapitolka je zařazena na úplný konec místo na začátek, ale pro praxi není zase tolik důležitá a její umístění tomu odpovídá.
S jakými názvy se tedy v souvislosti s MVC setkáte?
- Když někdo o MVC mluví jako návrhovém vzoru, tak buďto dělá chybu, nebo pojmem „návrh“ myslí něco jiného, než je zvykem (patrně myslí architekturu). Vztah návrhových vzorů a MVC je takový, že MVC je realizováno pomocí návrhových vzorů – např. notifikace změn v modelu může implementovat vzor Observer, Presenter může být pro View Strategií a podobně. Někdy se proto MVC označuje za „vzor (složený ze) vzorů“.
- Označit MVC za architektonický vzor je nejvhodnější, pokud je řeč o konkrétní variaci. S tímto označením se setkáte velmi často.
- MVC jako architektura se zase používá, když o MVC mluvíme zhruba na úrovni prvního článku této série, kdy rozdíly mezi MVC a MVP ještě nejsou tolik podstatné.
- Někdy se pak v souvislosti s MVC slyší pojem princip nebo přístup. Druhý zmíněný je asi lepší, protože slovo „princip“ má ve světě objektového návrhu konkrétní význam – patří sem principy jako Single Responsibility Principle, Open/Closed Principle a podobně.
- Ve světě konkrétních technologií dále často narazíte na pojem MVC framework, což je označení pro konkrétní implementaci nějaké variace MVC/MVP. Zde si dejte pozor na to, že za MVC se často označují i variace vzoru MVP, což je buď z neznalosti autorů (a pak se frameworku radši vyhněte), nebo z marketingových důvodů („C“ má větší marketingový potenciál než „P“).
- Poslední pojem, který se v souvislosti s MVC používá, je triáda. Často se tím myslí konkrétní trojice objektů realizujících třídy v modelu MVC. Toto označení je užitečné, když se o triádách mluví v množném čísle (triád je v aplikaci typicky mnoho).
Závěr
Pokud jste se prokousali až sem, gratuluji, nechybělo moc a byli jste lepší než autor. :) Přemýšlím, co by měla být hlavní věc, kterou si z této série odnesete, a je to asi toto:
Problematika MVC a souvisejících prezentačních vzorů je velmi složitá, ale určitě stojí za to se jí věnovat. Znalost architektonických vzorů vede k tvorbě kvalitnějších aplikací a dělá z běžných programátorů skutečné vývojáře.
Zdroje
Zdrojů o problematice MVC/MVP najdete mnoho, jejich kvalita však značně kolísá (například Wikipedia je v této oblasti bohužel plná polopravd, zavádějících tvrzení i vyložených omylů). Zde jsou některé materiály, které přímo nebo nepřímo souvisí s problematikou MVC a považuji je za přínosné:
- Freeman, Robson, Sierra, Bates: Head First Design Patterns – vynikající úvod do světa návrhových vzorů
- Martin Fowler: Patterns of Enterprise Application Architecture – katalog enterprise vzorů, obsahuje popis několika webových prezentačních vzorů
- Martin Fowler: eseje o GUI architekturách – primární orientace na widgetové technologie
- Derek Greer: Interactive Application Architecture Patterns – vynikající popis historického vývoje MVC/MVP včetně jednotlivých variací
- Jeremy Miller: Build Your Own CAB – série článků, demonstrujících jednotlivé vzory na reálném kódu
- Bob Martin: Agile Priniciples, Patterns and Practices in C# – ucelený pohled na problematiku principů objektového návrhu i jednotlivých vzorů. Některé části jsou dostupné i na webu.
Chybi mi odkaz na programatorovu statistickou rocenku :)
btw: Prvni! (poprve :-)
Pořád si nejsem jistý jednou věcí. Jak použít archtitektonický vzor MVC například v případě počítačového modelu auta.
Když si například zjednoduším auto tak, že jede stále po stejnorodé silnici (bere se v úvahu pouze sklon), mohou z něj ale nastupovat a vystupovat cestující (mění se hmotnost a poměr výkon motoru / hmotnost), ubývá a doplňuje se palivo (může úplně dojít), řidič ovládá spojku a převodovku (přechodové funkce), plynový pedál (křížová závislost odezvy na otáčkách motoru a bohatosti směsi, zatížení motoru) a volant. Takových automobilů můžete mít na scéně několik. K tomu postavy řidičů a cestujících (různé hmotnosti, styly řízení). Vše je v interakci se vším – vždy způsobem, který je pro každou dvojici možný. Nad tím sedí pozorovatel – uživatel, který například ovláda semafory, jedno z aut a pod.
Co je tu Model, co Controler a co View (Presenter)?
Převodovka každého z aut na scéně má zařazený nějaký převodový stupeň, ale to nezajímá nikoho jiného, než nanejvýcš instanci tohoto auta a jejího řidiče. Ostatní objekty zajímá až projev (důsledek) zařazení právě tohoto převodového stupně. V aplikaci ale může být zařazený stupeň nějak graficky indikován pro vnějšího pozorovatele a on do nastevní může zasáhnout.
Chápu to dobře, když si mylím, že MVC se musí vždy uplatňovat pouze na úrovni své vrstvy. Tzn. že převodovka jako třída má vlastní vnitřní MVC, rozčlenění, poskytuje rozhraní (V, C) a nadžazené auto jako celek s ní prostřednictvím jejího V, C komunikuje podle potřeby ve svých částech M, V i C a poskytuje dále V C rozhraní řidiči (řadící páku – indikace zařazení stupně + možnost změny)? Je to pořád MVC?
Ještě doplním, že se jedná o aplikaci, která nečeká jen na odezvy uživatele u klávesnice. Pořád se v ní něco děje a zpracovávají se tedy i vnitřní události bez ohledu, jestli uživatel reaguje nebo ne.
Záleží,co přesně chcete v systímu dělat-sledovat.
Tohle už ale určitě není vhodný scénář pro MVC. V Real Time vzorech se pro tyto typy apliakcí používá tzv. Data Bus.
Data Bus představuje variaci na vzor Observer, ale objekty, které se notifikují o událostech, jsou od sebe více odděleny, mohou poicházet z vícero vrstev a většinou se notifikují vzájemně (jsou "subject" změn i "observer" dalších změn – veškeré změny jsou ale distribuovány přes Data Bus, který může mít pull a push variantu.
Zde je alespoň letmý úvod – http://my.safaribooksonline.com/0201699567/ch08lev1sec5
Jasně, tak to i řešívám … každopádně díky za odkaz.
Jde mi o to, že by se mělo říci, pro jaký typ problémů se MVC dá použít. Jaké podmínky v charakteristikách modelovaného systému musí být splněny. Protože ani kávovar v jiném článku také není zrovna nejšťastnější příklad – je závadějící, protože skutečná mašina je real-time systém.
Budeme-li precizní,tak každá aplikace je real-time, protože uživatel také potřebuje vidět výsledky v reálném čase. :)
Obecně – MVC je vhodné pro aplikace, v nichž je potřeba odělit odpovědnosti související s generováním uživatelského rohraní a zpracováním vstupů z uživatelského rozhraní.
Formálněji – aplikace, pro něž je uživatelský vstup předpokladem spuštění právě jedné business transakce, kdy MVC se zabývá získáním vstupu (View), distribucí vstupu přes controller do vstupní části modelu (mimo odpovědnost MVC je interní zpracování business trasakce v modelu – interní komunikace mezi objekty, synchronizace stavů, obalení business trasakce třídou Unit Of Work, normalizace business transakce na atomickou databázovou transakci) – MVC pokračuje renderováním nového view – view se seznamem chyb, pokud business trasakce selhala, jinak další "normální" view, redirect apod. A tady začíná svět různých variací na MVC vzor.
Slovo "právě jedna business transakce" u webových aplikaci je samozřejmě míněno v kontextu jednoho požadavku jednoho uživatele na webový server (business transakce specifická pro request). Takových (izolovaných) požadavků v jednom okamžiku na jeden webový server je samozřejmě libovolné množství.
Většinou se mluví o tzv. LOB (line of business), "Data centric" aplikace.
U real time aplikace většinou musíte řešit velké množství simultánnních a na sobě nezávislých transakcí reaktivních objektů.
No, pak je real-time úplně vše :o)
Měl jsem na mysli systémy, které nečekají na podnět, ale pracují samy neustále mění vnitřní stav.
I když on ten kávovar vlastně lze brát jako tiše čekající na podnět a pak sice provádějící sadu vnitřních procesů, ale tam se nejedná o nic jiného, než naplňování cíle: výdeje kávy.
MVC je prezentační vzor, tudíž je vhodný pouze pro uživatelské rozhranní automobilu. Krásným příkladem by byla přístrojová deska. Controller by v tomto případě byl jedním z účastníků ServiceBus komunikace o které psal René. View jsou kontrolky, displeje a ciferníky.
MVC rozhodně není architekturou aplikace samou o sobě, ale pouze části, která má na starosti uživatelské rozhranní.
Ano, a pokud bych potřeboval zahrnout i vzájemné iterakce přístrojů, rodělil bych to dál … je to tak?
Takže MVC lze použít u objektů, které se mohou z mého pohledu jako celek chovat jako černá skříňka a uvnitř nich není potřeba řešit události, prostě mění stav pouze na základě podnětu zvenčí.
Vyvozujte ukvapené závěry.
Měřič zobrazované veličiny (rychlosti, otáček, obsahu nádrže) přece není i budíkem na přístrojovce, ale je v tomoto pípadě součástí modelu. Měřič může vyvolávat událost
SpeedChanged
a controller tuto událost zpracuje a změní view.No, to asi pořádně nečtete – nemluvím o měřiči, ale o jeho části: přístroji …
Takže znovu … pokud je budík součástí panelu a nepotřebuju po něm více, než view, pak můžu oddělit logiku zpracování signálů od přístrojovky jako celku. Pokud mne zajímá i interakce mezi budíky na palubce (což je praktický případ například simulace vzájemného ovlivňování vlivem změny teploty, nebo magnetického pole), pak musím palubku rozsekat na menší části. Každá z nich bude mít vlastní "MVC", a to už z principu. Je jedno jak to napíšu a v kódu zašmodrchám nebo uspořádám. Jedná-li se o černou skříňku, musí mít nějaké rozhraní (V s vstupními porty), systém pro zpracování podnětů (C) a vnitřní stav a definovaná pravidla pro jeho změny a generování zpětných odezev. Může to být libolně zamícháno, nebo rozčleněno.
Proto je možná kolem MVC tolik dohadů, protože není dost obecný. Myslím z hlediska reality a potřeby modelování.
Dobrý den, pokud tomu dobře rozumím, ptáte se, jak realizovat jednotlivé MVC triády (otáčkoměr bude "jeden malý MVC", tachometr druhý a tak dále). To je velmi dobrá otázka a podobný problém se řeší dnes a denně především v desktopových aplikacích, kde místo palubní desky a budíku máte většinou věci jako hlavní obrazovku, několik oblastí uživatelského rozhraní a potřebujete je provázat do jednoho funkčního celku.
Jak jsem psal v článku, popsat obecné řešení je dost těžké, protože hodně závisí na schopnostech dané technologie. Typicky narazíte na to, že Model je svým způsobem globální (i když jeho části můžou být do jednotlivých komponent injektovány) a pro každé View existuje odpovídající Presenter, případně je to celé potom doplněno globálním Controllerem, který má na storosti pouze velmi obecné, "provazující" záležitosti.
Ve vaší aplikaci buďto můžete vyzkoušet několik různých přístupů a vybrat si, který vám a dané aplikaci vyhovuje nejlépe, nebo se spolehnout na nějaký "architektonický MVC framework", který obvykle bude obsahovat návody, jak v konkrétní technologii tento scénář realizovat.
Díky za zajímavou otázku!
Ne-e :o)
Neptám se, jak realizovat MVC. Ptám se, kde jsou hranice jednoho MVC svazku, jaké jsou podmínky pro rozčlenění kódu dle MVC. Obecné řešení nesmí být závislé na technologii. Paralelu MVC musím být schopen vystopovat stejně tak v železe (konstrukci reálného auta), jako v kódu programu, nebo i v biologickém organismu – pokud to není možné (myslím obecně, nezávisle na mé dovednosti cokoli rozpoznat), není MVC nic jiné než logicky vypadají, leč zavádějící myšlenková pastička, nebo jen zvláštní forma řešení nějaké obecné rovnice, závislosti, problému – podobně jako je Bernulliho rovnice jen speciální formou obecné Navier-Stokesovy rovnice prodění tekutin.
Domnívám se, že MVC je nanejvýš speciální formou řešení obecného kybernetického problému černé skříňky … dám to následně do samostatného vlákna …
Nejak nerozumim vasemu pojeti servisy. V prvnim dile jste psal:
Pro me je ale servisni vrstva prave to, co obsahuje business logiku provadenou nad domenovymi objekty. Controller ma odkaz na servisu, ta obsahuje business logiku a pouziva DAO vrstvu pro persistovani objektu. Model jsem vzdy bral jako zapouzdreni vsech techto veci a proto mi vzdycky byla divna i vazba V na M, protoze si nemyslim, ze V by mel drzet odkaz na veci jako jsou servisy… Samozrejme by mel pracovat s domenovymi objekty — pak by se vazba V -> M dala chapat.
Takze nejen ze mi pripadne divna servisa mimo M, pripadne mi divne i to, ze vazba servisy na M je nepovinna (protoze i kdyz jde o webservisu, ktera nepracuje treba s lokalnimi domenovymi objekty dane aplikace, Controller to vubec nema co zajimat, on proste interaguje s Modelem – tedy jeho „vyslancem“ v podobe servisy — a odkud ten bere data neni vubec jeho vec).
Kdyz mam tedy aplikaci pracujici s informacemi o nejakych odobach, mam controller, ten drzi odkaz na PersonService a ta pracuje s objekty tridy Person a uklada je treba pres PersonDAO nebo neco takoveho…. co je tedy podle vas MODEL? Jen Person? A jak ma vypadat vazba V na M?
Business logika patri do modelu, service layer pak zajistuje akorat perzistenci domenovych objektu, a jak je v clanku napsano, nejlepsi je ho schovat za interface.
Vazba V -> M je pokud to dobre chapu read-only, view umi zobrazit data modelu, ale editaci zajistuje controller (presenter).
Co se tyce vazby controlleru na service, tak ta je potreba prave pri ukladani zmen, naplnovani ruznych seznamu atd.
ad aplikace o osobach: ano model je Person.
Docela casta chyba, s kterou ste se mozna potkal, je kdyz model obsahuje pouze data a zadne chovani, cela logika se nachazi jinde v systemu, napr. prave v servisni vrstve. To je spatne, mam pocit ze se tomu rika anemic models…
Hmmmm, no ja anemic models nepovazoval za takove zlo…. :) Ale kdyz tak koukam na Wikipedii, tak ta uvadi SoC jako jedinou vyhodu, tak si to budu muset jeste prostudovat :)
Kazdopadne spatny je i druhy extrem. Kdy to ujede tak, ze v domenovych tridach je logika, kterou v realne problemove domene ta entita nevykonava.
Dobrý den,
v zásadě za mě odpověděl bh3, jen dodám, že některé komentáře k servisní vrstvě najdete v mé odpovědi Renému Steinovi níže.
Čekal jsem, až bude série článků ukončena, abych poznal, jak Borek pojímá MVC.
Musím říci, že ale ani po přečtení celé série nejsem moudřejší.
Než se začít dohadovat nad "vysokoúrovňovými" věcmi, vždy se rád nejdříve shodnu na tzv. myšlenkových a implementačních trivialitách, protože na nich se pozná, jak člověk přemýšlí. Epochálním a letmo načrtnutým megalomanským "architektonickým" stavbám se těžko oponuje, protože žijí ve světě svých nezpochybnitelných a vždy při nárazu kritických připomínek rychle upravitelných předpokladů.:)
Citace:
"Komponenta chovající se jako Autonomous View v sobě kombinuje uživatelské rozhraní a další logiku, ať už prezentační, aplikační, doménovou, nebo jejich mix. V PHP budiž příkladem skript, který na začátku načte data z MySQL databáze a pak je pomocí různých podmínek a cyklů vypíše do HTML."
Zde se míchá několik věcí dohromady:
Nemělo by spíš zaznít.
Autonomous View v sobě kombinuje veškerou logiku, která se týká správy a udržování stavu uživatelského rozhraní. Tedy autonomous view přebírá role, které jsou při separaci různých odpovědností souvisejících s řízením uživatelského rozhraní rolemi samostatných tříd controller-presenter. To je téma tohoto článku.
Další (odstrašující, fakt jsm se lekl :) ) příklad už nesouvisí s probíraným vzorem (vzory). Můžete mít autonomní pohled, který jako podkladový model používá běžný business model, nebo anemický business model, anebo jen sadu transakčních skriptů, či rovnou přistupuje do SQL databáze. I M v MVC model může být označením pro transakční skript nebo jen sadu metod, které vracejí po předání SQL "resultset-recordset".
Příklad s PHP tedy představuje extrém a atypické použití autonomního view.
Přijde mi to ale jako hezký návod pro vývojáře, kteří píšou špagetový kód bez jakéhokoli rozvrstvení aplikace, aby mohli na pohovorech na otázku:"Jak píšete typicky webové aplikace", odpovědět jinak než "seberu data z databáte a pak už je pěkně v cyklu vypíšu, jaké komplikace woe". Nyní mohou rafinovaně říci : "Pro své jednoduché aplikace jsem namísto typického bastlení použil zjednodušenou a velmi efektivní variantu VZORU autonomní pohled. Mou domněnku potvrdil autoritativní zdroj, samotný velký Zdroják!" :)
Citace:
"Jestliže je MVC architekturou prezentační vrstvy aplikace, možná se ptáte, jak aplikace komunikuje s okolním světem. Musí přece nějak data do modelu načíst, ať už z lokálního disku nebo třeba z databáze. Často přece potřebuje komunikovat s nějakou webovou službou nebo něco na ten způsob. Kde tedy žije tato funkcionalita
Umístit ji do modelu je možné, ale nešikovné. Například třída, která implementuje zákazníka a současně dokáže jeho data uložit na disk, porušuje Single Responsibility Principle. Odpovědí je tedy oddělení čtvrté části aplikace, které se říká servisní vrstva (Service Layer)."
Tady už je to na mě příliš a univerzální zaklínadlo Single responsibility principle, kterým se tlučou po hlavě všichni předpokládaní heretici, k mé duševní pohodě nepřispívá.
Tedy servisní vrstva: Co přesně označuje?
Zkusme vyjít ze dvou příkladů v článku.
1) Zákazník a jeho uložení dat na disk.
Pokud vyjdeme z klasického vícevrstvého modelu, tak naším zájmem by mělo být, aby za ukládání zákazníka odpovídala perzistentní vrstva, kterou používají další (vyšší-např. business vrstva) vrstvy aplikace. Ano – ze zákazníka (business vrstva-tedy Model) určitě vydělíme odpovědnost za ukládání svých dat, vytvoříme nějaké společné rozhraní, které realizuje objekt v db vrstvě a v okamžiku, kdy má dojít k uložení dat, objekt zákazník po zavolání jeho metody UložSe může zavolat metodu z databázové vrsty Ulož, které předá svoje data. Samozřejmě nechceme-li mít delegující metodu UložSe přímo v objektu zákazník, nic nám nebrání vytvořit v Modelu další (podpůrné) objekty typu Data Mapper, které interně volají metody databázové vrstvy a objekt Objednávka nemá ve svém veřejném rozhraní žádné Kainovo znamení (metodu UlozSe)signalizující – jsem SW objekt a proto podporuji perzistenci, což by někteří dogmatici mohli považovat za porušení 11. přikázání (pardon, vlastně jen ončas užitečného SRP doporučení).
Důležité je, že Controller, tak jak je naznačeno v článku, NEPOUŽÍVÁ žádné servisní objekty pro uložení, ale pracuje s business modelem a poté, co potřebuje uložit data, zavolá příslušnou metodu business objektu, data mapperu apod, a poté je volání přeneseno na perzistenční vrstvu.
Servisní vrstva, o které je řeč v článku, připomíná spíš právě vrstvu složenou z repozitáře objektů a data mapperů, ale je popsána na zavádějících příkladech a podpírána (alespoň) nevyslovenými předpoklady – možná.:)
Citace:
"Controller testovat a nemusely se přitom používat reálné externí systémy, které mohou být pomalé nebo způsobovat jiné problémy. Pokud mám tedy např. v aplikaci službu EmailService, schovám ji za rozhraní IEmailService (nebo ještě lépe IMessagingService) a controlleru během testování předám FakeEmailService, která text jen uloží do souboru nebo třeba neudělá vůbec nic. Testování tohoto typu dále usnadňují tzv. mock frameworky, které se dají nalézt pro většinu dnešních technologií."
Základní otázka zní – k čemu controller, jehož odpovědností je ve všech možných inkarnacích zprostředkovávat komunikaci mezi View a modelem, jak nám bylo v článku několikrát naznačováno, najednou potřebuje emailové služby? Je to chlapík ten controller, všichni ostatní participanti jsou chudáčci, kterým musí odlehčovat v jejich odpovědnostech, ale tady si na svá tajemná, ale beze všech pochybností mohutná a altruistická záda naložil sadu dalších odpovědností.
Není to tak, že pravidla, kdy mají být odeslány emaily(emailové notifikace), je součást business pravidel? A je tedy odpovědností samotných objektů "modelu" (např. v objektu, který implementuje stavový automat pro objednávku), že poté, co uživatel dá příkaz ve View (kliknutí na tlačítko, submit) ke stornování objednávky, controller tento příkaz přenese do stavového automatu, ve stavovém automatu dojde k přechodu do stavu Storno a současně se spustí akce, která přes speciální servisní vrstvu pro odesílání emailu (IEmailService) odešle notifikaci.
Ano – controller může chtít odesílat také emaily (např. informaci o nějaké chybě/logovací informace) a pak může využít také služby objektu skrytého za rozhraním IMessagingService. Ale jak to souvisí s tímto vzorem a s vazbou controlleru na model a servisní vrstvy na business model?
Co by ale mělo platit:
Implementace rozhraní IMessagingService patří do nízkoúrovňových vrstev aplikace, rozhraní IMessagingService nemá žádné předpoklady, tedy nevidí v žádném případě jejich rozhraní, ani o objektech z business vrstvy, natož z controlleru. Je to služba s jasně vymezenou jednou odpovědností, voila, ani jsme se nemuseli opakovat magicou říkanku SRP.
IMessagingService
{
bool Config(Map configValues)
void SendMessage(string message, string subject, int priority …)
}
Nejlepší rozhodnutí jsou ne ta, která vás při návrhu baví, ale která vyplynou z požadavků. :)
Dovedu si představit služby využívané přímo controllerem, které mají přímo vazby na třídy v "Modelu". Například jde o fasády, které realizují uživatelské scénáře a ještě více izolují controller od modelu. Ale to je téma spíš na celý článek.
Už teď je můj komentář příliš dlouhý – snažil jsem se ukázat, v čem mi přijde článek spíše matoucí, než že by byl tím kýženým světlem, které nám, zneuživaným ovečkám, co podlehly krysařům vyluzujícím falešné MV*tóny, po desetiletích tápání ukáže tu pravou cestu, kde nebudeme hhlavně řešit tím, že si pleteme presenter a controller. Ta naznačená distinkce mezi controllerem a presenterem je totiž také zvláštní.
I v desktopové aplikaci se dá běžně použít (a já běžně používám) Front Controller a sada controllerů-presenterů v pozadí.
Např. (i v MDI) aplikaci tlačitka, položky v toolbaru a položky menu se po svém stisku pošlou do controlleru svůj "identifikátor-klíč", front controller podle klíče vyzvedné controller (realzovaný většinou vzorem Command) pro danou "akci", zavolá jeho metodu Execute a controller si uloží do seznamu provedených akcí, aby mohl např. akci odvolat. Pak je zajímavé řešit, jak může controller pomoci při realizaci undo-redo scénáře, jak si poradit ve webových a desktopových aplikacích s controllery, které udržují-neudržují vlastní stav. To je přímo na sérii článků.
Články mají za mě několik dobrých a kvalitních odstavců, ale z valné vštšiny jde spíše o kompiláty názorů z Domain Driven Designu, postupů v ASP.NET MVC, Silverlightu, něco předpokládaného z Dependency injection apod. Slovo kompilát není míněno nijak pejorativně, naopak dobrý kompilát by se v češtině určitě hodil, ale vadí mi Borku, že své vlastní termíny a předpoklady moc nevysvětluješ. Navíc, třeba Domain Driven Design má své vlastní problémy, na které člověk narazí při prvním pokusu o implementaci. Ale to je už opravdu zcela jiné téma.
Díky za komentář. Jak jsem už psal přes Twitter, jakoukoliv polemiku vítám a tato je navíc zajímavá tím, že sérii hodnotí jako celek, což je vždy užitečný feedback.
Z celkového vyznění a poměrně velkého počtu sugestivních obratů mám pocit, že vám články poněkud leží v žaludku, což je zvláštním způsobem zajímavé – úvodní motivací pro napsání těchto článků byl totiž podobný pocit, který jsem míval při čtení některých cizích zdrojů. Teď se tedy ocitám na druhé straně barikády :) K některým poznámkám:
* Autonomous View, pokud je mi známo, není striktně popsaný vzor a jeho výklad se může lišit. Vy považujete Autonomous View za kombinaci V a C, pro mě to je kombinace jakýchkoliv zodpovědností s View, tedy třeba i M+V+C. Příklad PHP skritpu uvedený v článku je podle mě v pořádku, a pokud ho považujete za extrémní a atypický, asi jste nikdy neměl tu "čest" přebírat po někom zběsile vytvořený projekt, což vám upřímně závidím :)
* Autonomous View vzor "bohužel" je. Jestli tuto informaci někdo zneužije na pohovoru, neovlivním.
* Vašemu odstavci o SRP nerozumím, žádné "předpokládané heretiky" po hlavě nebiju. SRP je široce uznávaný princip dobrého objektově orientovaného návrhu, který lze jako každý jiný princip nadužívat nebo zneužívat, to všechno ano, ale s článkem souvisí jen okrajově, proto taky SRP jen zmínkou.
* Debata okolo servisní vrstvy je zajímavá. Pár poznámek k tomu:
– Pokud se mi správně podařilo vydestilovat základní myšlenku z vašeho komentáře, podle vás by šipky měly vést ve směru C -> M -> SL a naopak by neměla (nebo nemusela) existovat přímá vazba C na SL. Máte pravdu, že v tomto bodě je článek možná trochu normativní – dokážu si představit, že vazba z M na SL existuje a asi jsem to měl zmínit. Přesto mám za to, že odeslání e-mailu je zodpovědnost aplikace, tedy aplikační logiky, tedy Controlleru. To, že nějaké pravidlo o odesílání emailů existuje v Modelu, na to nemá vliv. Nesouhlasím s vaší implikací "pravidlo je definováno v Modelu, tudíž by jím mělo být i realizováno".
– Kód, který ukazujete pro IMessagingService, je dobrým příkladem servisní vrstvy bez vazby na model. Tato struktura je zmíněna v článku.
– Celkově si myslím, že se v zásadě u servisní vrstvy shodujeme až na pár relativních detailů (podle vás existuje vazba M na SL vždy nebo aspoň typicky, pro mě je tato vazba nepodstatná nebo někdy nežádoucí).
– … a vlastně ještě něco – zajímavá debata by byla o vámi zmíněné "vrstevnatosti", kde, pokud jsem vás správě pochopil, bych si dovolil nesouhlasit. Odvedlo by to ale diskuzi jinam.
* Možnost současného použití Controllerů i Presenterů je v sérii zmíněna. Dokonce přesně v kontextu, který popisujete vy (Front Controller + sada Command objektů). Nejsem si jistý, jestli je váš komentář námitkou nebo prostým zopakováním?
* Ano, série je kompilátem mnoha různých zdrojů, jako všechny ostatní zdroje o MVC mladší deseti let. Přesto jsem se snažil přinést přidanou hodnotu, což se snad podle pozitivních ohlasů podařilo.
Nyní, když jsem odpověděl na vaše komentáře a zjistil, že se vlastně lišíme jen v relativních detailech, přemýšlím, co vám na celé sérii tak fundamentálně vadí. Pokud je to nevysvětlení některých předpokladů, jak píšete, může to být pravda: například předpokládám, že čtenář ví nebo aspoň tuší, co je prezentační logika, aplikační logika, prezentační vrstva v třívrstvém modelu a podobně. Důvod je prostý: když má být článek dobře čitelný a vejít se do rozumného rozsahu, nemůže zaběhnout do každého souvisejícího detailu (a že jich ve světě MVC je!). Můj limit byl cca 30 000 znaků na celou sérii, tedy 10 000 znaků na článek a věřte mi, že jsem musel vyhodit hodně věcí, abych se této metě aspoň přiblížil. Výsledkem je něco, co se snad dobře čte a představuje rozumné shrnutí problematiky MVC, i když je mi jasné, že se nemůžu vždy zavděčit každému. Naštěstí vy osobně rozhodně eseje o MVC číst nepotřebujete, takže i když vám třeba série nesedla, můžu s tím docela dobře žít :)
Díky za komentář,
B.
Díky za reakci, snad jen na vysvětlení.
Články mi "poněkud" ani zcela v žaludku neleží. :) Mrzí mě, pokud to tak vyznělo, snažil jsem se o vstřícné čtení a motivaci komentáře jsem popsal hned na jeho začátku. :) Navíc bych řekl, že některé další reakce mi dávají za pravdu.
Hnidopišské čtení by, věřte mi, vypadalo zcela jinak a mým cílem nebylo nijak sérii shodit. BTW: Na twitteru jsem posílal včera i DM, která podle mě také nevstřícná nebyla…
Jen na objasnění "sugestivních" obratů a ironie (hlavně kolem) SRP. Tyto části jsou jen a pouze pobavenou reakcí na jeden váš (pro mě) zvláštní a za hranicí vstřícného "čtení" článek, který ve formě školometského mentorování reagoval na kód a článek AD. Víc tady nemá smysl dodávat.
SRP nezpochybňuji, jen se bavím tím, když někdo princip-obušek vytáhne a pak většinou po vyřknutí všech OOP zaklínadel o "změnách z jednoho důvodu" skončíme na tom, co je to ta jedna odpovědnost (a jak se projeví v rozhraní třídy. V komentáři jsem poté u IMessagingService podotýkal, jak k SRP třídě dojdeme.
Takže jen pár postřehů:
Ad Autonomous View) Tady předvádíte nevstřícné čtení vy.
Nechápu, jak se na podstatě Autonomous View projevuje, fakt, jestli jsem přebíral nebo nepřebíral po někom zběsilý projekt. Jestliže Vy jste takový projekt přebíral, víte proto lépe, co je to Autonomous View? Neboli – když říkám, že váš příklad je atypický a extrémní, protože zamlžuje, jak je Autonomous view konvečně chápáno, tak vy mi podsouváte, že říkám zcela něco jiného: "Extrémní je výskyt takovýmto způsobem 'zběsile vytvořeného' projektu" v našem světě (nebo mě litujete, že se ke mně se takové zbastlené projekty nedostaly, jsem Tomáš, který nevěří ve všemocná programátorská prasata a nemůže tudíž ani uvěřit v těžký kříž chudáka vývojáře, co přebírá cizí projekty a jehož čas vyplňuje refaktorizace čuňačin skrytých pod rouškou autonomních view:) )? To snad je jen nedorozumění.
Konkrétněji – hledal jsem, kde můžete mít pro tato svá tvrzení oporu. A i u ve Flexu, který je Vám blízky
"The vision at the core of the Autonomous View pattern is one of smart reusable components glued together to form a hierarchy of composite views. In extreme cases, business logic and interactions with remote-services are also implemented directly in the views. ****But many Autonomous View architectures do attempt some extraction of this kind of logic into separate classes for use by multiple views."****
Zdroj: http://weblogs.macromedia.com/paulw/archives/2007/09/presentation_pa_1.html
Vzory se mohou nazývat vzory, když je jasné, jaký problém vzor řeší a jaké jsou jeho variace. Vymlouvat se na to, že Autonomou view není dobře popsán, no ehm – proč pak ale o něm mluvit jako o vzoru, jde o pouhý draft, který spíš mate než vysvětluje. Proč tedy nezavedete svůj pojem pro popsání toho, co máte na mysli a nepodáte jeho definici?
Zbaslený kód může být jedině antivzorem, anebo tedy mohu začít zbastlené projekty popisovat jako tradiční exempláře vzoru Autonomous View, který vznikl mírnou evolucí časem ověřeného programového idiomu "Spagheti Code". :)
Ad IMessagingService – uvedl jste dva příklady, já jsem se je snažil podrobně rozebrat a
dobrat se toho, co tedy servisní vrstva ve vašem pojetí v aplikaci představuje. Výhody Controlleru z prezentačního vzoru, který řídí odesílání emailů (kromě situace zmíněné v mém komentáři) mi unikají.
Poznámka k Front Controlleru – byl to jen závěrečný povzdech, že hranice mezi MVC a MVP jsou neostré. Rysy desktopových i webových aplikací se prolínají a kombinují. V desktopových aplikacích můžeme mít cosi, co je nazýváno application controller (jak jste v článku zmínil), ale mnohdy AC figuruje i v roli FC a hranice mezi MVC a MVP lze jen těžko nalézt. Navic, jak víte a částečně jste v článku zmínil, MVP u Fowlera je v *draftech* nakonec potlačen (Retirement note for Model View Presenter Pattern) a mluví hlavně o samostatných kandidátech na vzor Front Controller, Passive view (a Presentation model).
Školometská:) poznámka na závěr – článek jsem přečetl (kupodivu) rád a jsem rád, že vznikl, jen bych mu neříkal esej. :) Esej je podle mě subjektivně laděná odborná analyticko-syntetická úvaha, která předpokládá u čtenáře obeznámenost s tématem, neobtěžuje se většinou s citací zdrojů, ale stávající poznatky obléká do nového neotřelého hávu nebo vyvozuje zajímavé důsledky ze stavu stávajícho vědění. Syntetický rekapitulující text mi do formy eseje nepasuje.
Autonomou view … proč pak ale o něm mluvit jako o vzoru … jedině antivzorem
On je ten vzor v případě AV zcela záměrně uveden v uvozovkách. Použití termínu antivzor by bylo jen poněkud ostřejší variantou téhož. To už je jen o tom, jak moc důrazně chceme na tu čarodějnici před spálením ukázat, aby se všem zošklivila.
Omlouvám se, ale vzhledem k času, kdy tato konverzace probíhá, teď nemám úplně čas ani chuť snažit se porozumět všemu, co píšete. Ve vašem komentáři se objevila některá klíčová slova jako "podsouvat", po kterých mi mozek silně doporučuje debatu ukončit a případně se k ní vrátit někdy v budoucnosti, v lepších a klidnějších podmínkách, třeba jak jste navrhl v DM přes Twitter.
Pár věcí, které chci, aby zazněly už tady:
* Slovo vzor používám v jeho nejobecnějším významu, tedy jako něco, co se opakuje. Antivzor, pořád vzor. Jinak, jak píše Martin, uvozovky nejsou v textu bezdůvodně – čtenář by měl pochopit, že když u AV říkám vzor, nemyslím úplně to samé jako vzor u MVP, MVVM apod.
* Všechny články Paula Williamse jsem četl a záměrně na něj neodkázal, protože občas uvádí zcela mylné informace (můžu najít, kdyby byl zájem). Tím netvrdím, že zrovna vámi uvedená citace obsahuje nějakou chybu, ale prostě ho nepovažuji za spolehlivý zdroj.
* Osobně považuji rozdíl mezi C a P za poměrně ostrý a dokonce bych řekl, že moje argumentace o tom, v čem ten rozdíl je, nabízí poměrně unikátní vysvětlení. Budu rád, když řeknete, jestli v této argumentaci vidíte nějaké problémy, případně kde tyto problémy jsou, ale to, myslím, zatím nezaznělo.
Pěkný večer,
B.
P.S. Případná reakce až zítra, dnes se půjdu věnovat příjemnějším věcem než je programování :)
Nevím co je to DM, AD, AC, FC a když je řekne SRP, očekávám KLADIVO.
PŘML se za SRML KMTŘ!
ps.
PŘML = přimlouvám
SRML = srozumitelnější
KMTŘ = komentáře, vole
… tak borek dostavel raketoplan (nebo house-of-pain?) :)) existuje takovej vybornej anglickej termin: "brainfuck" – taky mi to pripomina prdeni hlavou – tak sem si rikal jak dlouho clovek musi prdet nez s tim zacne neco delat :) myslim ze je zde taky docela jasne videt proc nema cenu na neco takovyho psat 'kontruktivni' kritiku protoze timhle stylem bysme u toho stravili mladi (v mem pripade stari) nezbysme k necemu dospeli :) myslim ze je na case zacit myslet (hlavou) … :) timto nechci autora urazit – prosim ber to s humorem – ja sem se bavil cele tri dily a doufam ze se jednou zasmejes i ty :) at se dari! :)
Co si přesně mám představit pod servisní vrstvou a kdo je zodpovědný za vytvoření její instance? Mám si pod tím představit DB layer jako třeba Dibi? Anebo ten bude touto vrstvou obalen?
O vytvoření její instance se stará Presenter/Controller?
V pojetí MVC je DB layer Model. To je v článku vysvětleno.
Logicky se dá odvodit, že při řešení určitých problémů je třeba zvolit oddělenou vrstvu která se může volat odkudkoli a bude velmi jednoduché udržovat a upravovat logiku zpracování.
Například generování a stahování XML feedu je dobré oddělit a napsat samostatnou třídu, která řeší tento feed jako individuální (používá určité značky) volá se cronem přes controller a využívá model pro spojení s databází. Pak je velmi jednoduché, například při změně nejakých značek nebo struktury feedu zasáhnout a neřešit logiku návrhu aplikace.
V pátek jsem řešil problém práv u obsáhlejší aplikace a dospěl jsem k oddělené vrstvě, která se volá z controlleru (kontroluje akce dostupné uživateli) a zároveň z view kdy kontroluje zda má uživatel právo vidět určité odkazy. Při tom používá model, který tato práva ověřuje v databázi. Do budoucna bude tato vrsva mnohem robustnější a nebojím se dál na tomto stavět, protože mám opět vyřešenou logiku aplikace, jen se postarám o pravidla ověřování.
> V pojetí MVC je DB layer Model. To je v článku vysvětleno.
Kde, prosím?
Db layer minimálně těžko bude mít business logiku => těžko může být modelem.
Pro RSS je tu prostě jiný view.
Zbytečně zacházíte do implementačních detailů.
Jak psal Aleš, konkrétní podoba přístupu do databáze není na této úrovni podstatná. V některých aplikacích uvidíte přímé použití nějaké databázové knihovny a v jiných zase mezivrstvu (např. Repository).
Co se instanciace týče, obvykle se tak děje při startu aplikace. Já osobně bych to Controllerem nenazval, ale terminologie mi na tomto místě nepřipadá podstatná – pokud tomu někdo chce říkat Controller, proč ne.
Chcel by som sa tymto spytat kde presne patri navrhovy vzor UI Delegate pouzivany v ramci Java Swing. Jedna sa len o iny nazov niektoreho zo spomimanych vzorov, alebo ide o uplne odlisny vzor???
Java Swing dopodrobna neznám, ale pokud jsem z dokumentace vyrozuměl správně, UI Delegate je jakousi kombinací View a Controlleru. Design nízkoúrovňových komponent má ale svá specifika a obvykle se o detaily fungování tlačítek, vstupních políček a podobných prvků nemusíme starat.
UI delegate je podle me strategie pro kresleni – vsechno ostatni je stejne, jen vlastni tvary a barvicky jsou jinac. Opravi me nekdo?
P.S. Ještě bych chtěl poděkovat Aleši Roubíčkovi (http://www.rarous.net/) za přečtení seriálu před jeho vydáním a zaslání několika užitečných poznámek. Díky!
Vycházím z předpokladu, že aplikace se jako celek chová černá skříňka. Černá skříňka komunikuje s okolím pomocí signálů, vstupních a výstupních. Ke všem svým vnitřním částem má černá skříňka výhradní přístup, tzn. nesdílí je s jinou černou skříňkou jinak, než prostřednictvím rozhraní. Kombinace PHP+MySQL je tedy tvořena minimálně dvěma černými skříňkami PHP běžící instancí PHP scriptu a databází s databázovým strojem. Je to asi banální, ale podle mého je důležité si právě toto uvědomit.
Co je MVC z pohledu struktury černé skříňky PHP scriptu? "V" je druh výstupního signálu (výsledná HTML stránka). Generují se i jiné výstupní signály. Např. ukládání dat do cookies. "C" je systém pro zpracování pouze určité množiny vstupních signálů (URL dotaz, data s ním spojená). "M" je vše ostatní včetně výstupních a vstupních signálů směřujích k a od druhé černé skříňky s databází.
Popsal jsem to dobře?
Pokud ano. Je asi celkem jasné, v čem je MVC systém členění aplikace speciální a jak je tím vlastně zavádějící.
To, o čem mluvíte jako o "černých skříňkách", se v třívrstvém modelu nazývá vrstvami. MVC je prezentační vzor, aplikuje se tedy v prezentační vrstvě, ve vašem příkladu v PHP aplikaci.
M, V a C jsou poměrně detailně popsány v článcích, asi by nemělo smysl zde vše opakovat.
Jo-o i ne-e :o)
Ať se nazývá cokoli jakkoli, ať už máte jakýkoli model (abstrakci) reality, vždy je nejdůležitější jaká je technická podstata věci. Náhled na aplikaci pomocí struktury černých skříněk mohu porovnat s náhledem MVC a mně šlo o to, jestli jsem vzájemné porovnání udělal dobře. O tom v článku nic není.
Ať už se jedná o náhled na realitu pomocí členění do MVC, černých skříněk nebo čehokoli jiného, jedním z dosti podstatných důvodů, proč si jakékoli takové schéma zavádím je pochopit, co vlastně dělám, jak to funguje a má fungovat aby … a druhým, abych si následně zjednodušil práci a mohl se odpoutat od komplexnosti a zúžit svůj pohled na detail s jistotou, že to s čím v detailu (nebo obecně na aktuální úrovni) pracuji jsou skutčně celistvé stavební kamínky a ne jen se tak tvářící konce špaget.
Už mi rozumíte, co se snažím říci?
Když se pokusím MVC způsob pohledu použít v praxi, narazím na to, že je právě v tomto ohledu zavádějící. Ono je zdánlivě logické rozčlenění. Tváří se jako by vystihoval samu podstatu fungování aplikace, ale z výše uvedeného porovnání s jiným druhem abstrakce reality, černou skříňkou (která je podle mého realitě mnohem blíže, ale je otázka, jestli jsem to srovnání udělal opravdu dobře), prostě vyplývá, že v některých částech aplikace dělá z jedné odrůdy jablka jablko jako druh a na jiném místě míchá zbylé odrůdy jablek s hruškami.
Proto je ASI kolem praktického nasazení MVC tolik nejasností a je to tak náročné na detailní provedení. Protože člověk musí mít neustále na paměti, že v případě MVC není abstrakcí typu "podstata fungování", jakkoli se tak tváří, ale způsobem náhledu typu "paní radová, její knihkupec, jeho poznámkový blok a zbytek planety" :o)
… přesněji: "paní radová, její knihkupec, jeho knihkupectví a zbytek světa"
Nezvažoval jste někdy kariéru filosofa? :)
Asi trochu rozumím, co chcete říct, ale rozhodně ne natolik, abych mohl věcně komentovat. Pardon.
Pekna serie. Ale pro mou prirozenou natvrdlost ji mam schovanou a nekdy se k ni vratim. Dik. MVC a MVP teoreticky znam, ale ostatni moc ne…
Esce jsem zapomnel dodat, ze princip Jednoduche odpovednosti (trida/objekt ma za ukol jen jednu vec) mi stale dela problemy. Je to asi tim, ze vse vidim z nizkourovnoveho programatorskeho hlediska, uz premyslim, jak to napsat, a navrh z nadhledu ne a ne udelat. Treba tento tyden. Ale nikomu to nerikejte, kdyz se tim zivim :-).
Dík za pěkné články. Myslím, že jsem si v těch třípísmenných
zkratkách udělal výrazně větší pořádek než jsem měl před jejich
přečtením.
Ještě mi však nedá nepřidat ještě jednu zkratku. Nedávno jsem četl
o DCI a přišlo
mi to jako rozumná kritika MVC s pěkným návrhem jak z toho ven. Možná se
to někomu bude při navrhování hodit.
Přijde mi, že příčiny nepochopení jsou 2 hlavní.
V ASP.NET MVC tomu třeba nahrává i fakt, že hlavička generické třídy
ViewPage vypadá: „ViewPage<TModel>“.
Frameworku je spíš taková tendence, že controller předá view všechno, co
je potřeba, a view už nic jiného nepoužívá. Viz třeba examply a
dokumentace přímo od autorů obou frameworků.