Názory k článku
Alternativy k MVC a závěrečné poznámky
rocenka
celé vláknobtw: Prvni! (poprve :-)
příklad auta
celé vláknoKdyž 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?
Re: příklad auta
celé vláknoRe: příklad auta
celé vláknoTohle 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
Re: příklad auta
celé vláknoJde 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.
Re: příklad auta
celé vláknoObecně - 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ů.
Re: příklad auta
celé vláknoMě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.
Re: příklad auta
celé vláknoMVC rozhodně není architekturou aplikace samou o sobě, ale pouze části, která má na starosti uživatelské rozhranní.
Re: příklad auta
celé vláknoTakž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čí.
Re: příklad auta
celé vláknoVyvozujte 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.
Re: příklad auta
celé vláknoTakž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í.
Re: příklad auta
celé vláknoJak 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!
Re: příklad auta
celé vláknoNeptá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 ...
RE: Alternativy k MVC a závěrečné poznámky
celé vláknoModel jsou tedy data plus business logika (někdy zvaná doménová logika) aplikace. Teoreticky může být model pouhou sadou datových objektů bez business logiky, ale to je poměrně netypické.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?
RE: Alternativy k MVC a závěrečné poznámky
celé vláknoVazba 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...
RE: Alternativy k MVC a závěrečné poznámky
celé vláknoKazdopadne spatny je i druhy extrem. Kdy to ujede tak, ze v domenovych tridach je logika, kterou v realne problemove domene ta entita nevykonava.
RE: Alternativy k MVC a závěrečné poznámky
celé vláknov 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.
Můj mozkový controller (některé) názory této série odmítá :)
celé vláknoMusí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.
Re: Můj mozkový controller (některé) názory této série odmítá :)
celé vláknoZ 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.
Re: Můj mozkový controller (některé) názory této série odmítá :)
celé vláknoČ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.
Re: Můj mozkový controller (některé) názory této série odmítá :)
celé vláknoOn 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.
Re: Můj mozkový controller (některé) názory této série odmítá :)
celé vláknoPá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í :)
Re: Můj mozkový controller (některé) názory této série odmítá :)
celé vláknoPŘML se za SRML KMTŘ!
ps.
PŘML = přimlouvám
SRML = srozumitelnější
KMTŘ = komentáře, vole
Servisní vrstva trochu přesněji
celé vláknoO vytvoření její instance se stará Presenter/Controller?
Re: Servisní vrstva trochu přesněji
celé vláknoLogicky 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í.
Re: Servisní vrstva trochu přesněji
celé vláknoKde, prosím?
Re: Servisní vrstva trochu přesněji
celé vláknoPro RSS je tu prostě jiný view.
Re: Servisní vrstva trochu přesněji
celé vláknoRe: Servisní vrstva trochu přesněji
celé vláknoCo 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.
UI Delegate
celé vláknoRe: UI Delegate
celé vláknoRe: UI Delegate
celé vláknoRE: Alternativy k MVC a závěrečné poznámky
celé vláknoMVC(P) vs. černá skříňka
celé vláknoCo 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í.
Re: MVC(P) vs. černá skříňka
celé vláknoM, V a C jsou poměrně detailně popsány v článcích, asi by nemělo smysl zde vše opakovat.
Re: MVC(P) vs. černá skříňka
celé vláknoAť 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)
Re: MVC(P) vs. černá skříňka
celé vláknoRe: MVC(P) vs. černá skříňka
celé vláknoAsi trochu rozumím, co chcete říct, ale rozhodně ne natolik, abych mohl věcně komentovat. Pardon.
pekne
celé vláknoCo po MVC? DCI!
celé vláknoJeš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.
Re: pekne
celé vláknoK tomu nepochopení MVC
celé vláknoPřijde mi, že příčiny nepochopení jsou 2 hlavní.
- Někteří si myslí, že model je přepravka dat z controlleru do view. V ASP.NET MVC tomu třeba nahrává i fakt, že hlavička generické třídy ViewPage vypadá: „ViewPage<TModel>“.
-
- Šipka od view k modelu. Přijde mi, že v ASP.NET MVC nebo i Zend 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ů.