Rozdíly mezi MVC a MVP rubrika: Programování: Jiné

Anonym
položil/-a 4.3.2014

Na základě komentářové diskuse k otázce Struktura PHP MVC projektu jsem založil novou otázku aby diskuse nezapadla.

Jak chápete rozdíly mezi vzory MVC a MVP. Seriál o prezentačních vzorech lze najít na http://www.zdrojak.cz/serialy/mvc-a-dalsi-prezentacni-vzory/. Bohužel spoustě lidem vzory MVC a MVP splývají a je těžké definovat hranice.

Tak sem s Vašimi návrhy a postřehy. Případně jaké další návrhové vzory používáte místo MVC/MVP a proč.

odkaz
9 Honza Břešťan
odpověděl/-a 5.3.2014

MVC je asi relativne jasne:

  • Model jsou data a logika pro jejich ziskani a manipulaci. V idealnim pripade Controller zavola nejakou Model akci, a ten o vysledcich uvedomi View.
  • View uzivateli zobrazuje data z Modelu; dava vedet Controlleru, ze uzivatel neco chce.
  • Controller manipuluje s Modelem, vysledkem cehoz byva nejake View (ktere vytvari vetsinou ten Controller a jen mu preda Model), na kterem uzivatel uvidi vysledek te manipulace.

Uzivatelske akce musi nejaky Router poslat na spravny Controller, ktery pak resi vysledne View. I proto je to ale v podstate idealni pro web - server si nemusi drzet moc stavu, routovani umime pres HTTP "zadarmo".

Naproti tomu v MVP:

  • Model jsou data a souvisejici logika, ale nikoho nijak nenotifikuje. (V MS terminologii to je varianta "Passive View". Druha varianta, "Supervising Controller", je IMHO MVC)
  • View zobrazuje data, ktera mu da Presenter (tady zmena, zadne bindovani na Model), a deleguje na Presenter uzivatelske akce.
  • Presenter manipuluje s Modelem, ale zaroven se stara o "nakrmeni" View daty.

Protoze se akce nijak neroutuji (View vola svuj Presenter, Presenter vola svoje View), udrzuje se hierarchie Presenteru - takze zmenu View v dusledku resi parent Presenter.

Ja jako vic desktopovy nez webovy vyvojar, navic primarne pro .NET, jsem delal nejvic s MVVM (ve WPF):

  • Model je stejny jako v MVP, cili data a nejaka logika
  • View zobrazuje data, ktera si nabindoval z ViewModelu. Zaroven ViewModelu deleguje uzivatelske akce.
  • ViewModel podobne jako Presenter manipuluje s Modelem, ale misto cpani dat modelu mu je nabizi na binding a jako Model v MVC notifikuje View o zmenach. Binding resi jak data, tak commandy, takze castecne ten Binder (ve WPF automagicky a docela mocny) zastupuje funkce Presenteru a Controlleru, takze na samotny ViewModel toho moc nezbyva.

Podobne jako v MVP je potreba drzet hierarchii ViewModelu, aby mohl parent ViewModel resit prepinani Views.

Komentáře

  • Taco : Určitě bych se ohradil, aby model informoval view - pokud to není myšleno jako poslání obecné zprávy posluchačům, mezi kterými by mohl být zaregistrovaný i ten view. Ale ve většině případů je to blbej zvyk. 5.3.2014
  • Honza Břešťan : (Predpokladam, ze se bavime o MVC) Posilat obecne zpravy muze kdo chce kam chce. Timhle je myslene zobrazeni aktualnich dat, pokud se zmeni (treba vlivem jineho uzivatele). Na webu je takova notifikace na view bud pushnuta (idealni stav, protoze to nemusi resit controller), nebo se deje (long)polling, nebo se neresi. Pokud je model a view oboji na clientu, tak v pripade zmeny modelu by se melo ASAP zmenit i view (bez zasahu controlleru!), aby tu zmenu reflektovalo. MVC je pattern ze 70. let minuleho stoleti; neni puvodne webovy, takze treba tohle nedava pro web vzdycky smysl. 5.3.2014
  • Stefano : @jan-brestan - MVC "View uzivateli zobrazuje data z Modelu; dava vedet Controlleru, ze uzivatel neco chce." V pripade desktopovych app to zrejme bude pravda ale v pripade webovych aplikacii(nie SPA) som sa s takymto pristupom nestretol. 5.3.2014
  • Honza Břešťan : @Stefano: Co tam je jinak? Resp. jak bys to popsal pro web? 5.3.2014
  • siq : Nette je MVP a ma router. Ako to potom je? :) 5.3.2014
  • Stefano : MVC nie je definovany uplne presne. Diskusia na stackoverflow Which MVC Diagram is Correct? (Web app) Ja programujem v PHP a pouzivam MVC tak ako je zobrazeny na diagrame cislo 5 + tam este chyba sipka view - model. Router rozhodne ktory kontroler ma spracovat reguest. Kontroler spracuje request a posle data do view. View moze pomocou view helprov pristupovat k modelu ale len read-only. 5.3.2014
  • Honza Břešťan : @siq: Pak to IMHO neni MVP. Tam se routovani uzivatelskych akci per se neresi (moje pojeti se celkem blizi tomuhle http://aviadezra.blogspot.com/2008/09/mvp-model-view-presenter-design-pa..., ale abych se priznal, s MVP na webu mam presne 0 zkusenosti). Webserver to samozrejme resit musi, ale z pohledu MVP to je infrastrukturni vec a View aktivuje predem zaveseny Presenter (nebo AppController, aby to nebylo jednoduche) 5.3.2014
  • danaketh : @siq: Nette je MVC, které používá Presenter, protože Davídek tehdy moc bumbal :D 5.3.2014
  • Honza Břešťan : @stefano: Tak to chapeme podobne. Na tom 5. diagramu je celkem pekne ukazany uzivatel/browser, ktereho jsem z toho pro zjednoduseni vynechal. Asi to byla chyba, protoze jak na to koukam dal, to oddeleni uzivatelske interakce s controllerem od vysledneho view je i historicky celkem dulezite. 5.3.2014
  • Anonym : Děkuji všem a hlavně @Jan Břešťan za to, že to pěkně rozepsal, už je mi to jasnější a jak jsem tak koukal tak je toto dost kladená otázka. Co mě asi nejvíce mátlo je Nette. 5.3.2014
  • Honza Břešťan : Nemas zac. Jak ale vidis i tady, definice jsou ruzne a i tohle je jen "jak to vidim ja". 5.3.2014
  • siq : Ja si myslim ze tie hranice nie su az tak jednoznacne. 5.3.2014
  • rmaslo : Celkově je to hezky popsaný, ale stejně mám nějaké drobné výhrady. Začnu MVC. Tam se mi hlavně nelíbí "Controller zavola nejakou Model akci, a ten o vysledcich uvedomi View." Místo toho bych napsal "Controller zavola nejakou Model akci, a předá řízení View." Tím "předáním řízení" myslím třeba ve www kontextu buď redirect nebo pouhé "pokračování scriptu" (typicky v závislosti na POST/GET). Podle mě totiž komunikaci View-Model neinicializuje Model, ale inicializuje ji View, což mi přijde jako důležitý rozdíl... Dále "View dava vedet Controlleru, ze uzivatel neco chce." Tam se mi nelíbí, že by si to někdo mohl vykládat jakože view hned po svém vygenerování něco říká controleru. Napsal bych spíš "View vygeneguje seznam akcí z nichž uživatel jednu vybere a ta je odeslána controleru". Ale to je detail.... V bodu controller se mi nelíbí, že slovo view používáš jak pro název jedné části MVC tak pro název "jedné vybrané zobrazované struktury". To je trochu matoucí. Nebál bych se pro název té zobrazované struktury použít třeba slovo stránka (www kontext) nebo formulář (desktop kontext). Ale to je taky jenom detail... A nakonec bych poznamenal, že View by nemělo nikdy nic zapisovat do Modelu - aby byl jasný rozdíl mezi komunikací Controler-Model a View-Model. 5.3.2014
  • Kit : @rmaslo: View by do modelu neměl zapisovat a controller by z něj neměl číst data. Možná validační pravidla, pokud se někdo snaží v controlleru i validovat, ale v modelu se validuje obvykle mnohem jednodušeji. 5.3.2014
  • Roman Kubiš : Ja som myslel, ze vo View by sa uz ziadne data nemali dodatocne tahat z Modelu. Vsade sa pise, ze MVC pomaha zaroven organizovat kod tak, aby napr. s View mohol pracovat menej skuseny programator, resp. HTML/CSS koder, ktory vo View pracuje s datami, ktore mu pripavil Controller. Cize vo View by si mal vystacit s nejakym sablonovacim systemom. 7.3.2014
  • Kit : @Roman Kubiš: Ten šablonovací systém odněkud potřebuje vytáhnout data. Je zbytečné tím zatěžovat controller, ten má na starosti kompletaci modifikačních požadavků pro model. 7.3.2014
  • rmaslo : @Roman Kubiš: Jo taky jsem to párkrát slyšel - nesouhlasím s principem a obzvlášť ve webové aplikaci, kde často controler a view bývá odděleno redirectem (kvůli POSTu) si to absolutně nedovedu představit ani prakticky. Jak by se taková halda dat předala? Podle mě je k dispozici jen URL a cookies... 7.3.2014
  • Honza Břešťan : Podle me mluvite kazdy o necem trochu jinem. U Kita to chapu tak, ze view neopousti server. Je to soucast te serverove aplikace, ktera vezme model a vicemene ho v pripade webu zformatuje do HTML. To, co zobrazuje browser, pak neni view, ale vystup z view. Takze view si pak nic nikde netaha, protoze ta data uz davno dostal, vlozil do sablony a tim jeho prace skoncila. HTML dokument pak uzivateli dovoli skrz router volat akce na controllerech, ale uz se to vubec nijak netyka toho puvodniho view, ktere ten dokument vytvorilo. Chapu to spravne? Neco jineho pak jsou clientside MVC frameworky, kde ale nejde o to, ze by view delalo nejake dalsi akce. Pripadne hybridy, kdy serverside view vygeneruje dokument, ktery ale obsahuje nejake clientside akce - pak v nejlepsi pripade dotahuje subviews apod., ale tak jako tak nejde IMHO o "ciste" MVC. 7.3.2014
  • Honza Břešťan : @rmaslo: K tem pripominkam - vesmes souhlasim, mozna to pak jeste doedituju. 7.3.2014
  • rmaslo : @Jan Břešťan: Ano taky to chápu tak, že view server neopustí a v prohlížeči jsou je výstupy z view. Pokud chci něco "dotahovat" tak to, ale podle mě lze i s "zachováním čistoty MVC". Prostě si představím, že ta stránka není celistvá, ale je tvořena množstvím "iframů" a pro každý ten iframe zase platí MVC. To že tam nakonec místo iframu je ajax je už jen "technické řešení". Ale tím ajaxem leze zase jenom HTML. Pokud bych tím ajaxem posílal data a ty nějak formátoval v JS, tak už by se o čistě "MVC na srraně serveru" nejednalo, ale byl by to nějaký hybrid s částí view na serveru a s částí view v prohlížeči. Takto rozdělené view nemám rád protože to svádí k tomu, že ta formátovací část view se musí napsat 2x - jednou na serveru(v php - první načtení stránky) a jednou na klientovi (v JS - po axaju) a to se určitě bude zatracené blbě udržovat... Proto radši posílám HTML které na straně serveru "tou samou funkcí" vygeneruje vždy stejně. 8.3.2014
  • kacerr : @rmaslo: Takze kdyz budes mit v aplikaci nekolik ruznych zobrazeni toho sameho (rekneme ze treba clanek na homepage, pak nekde v archivu, v searchi ... proste stejna data, jen jine formatovani) tak si na serveru udelas tri ruzny HTML vystupy a az do budes pomoci ajax callu "dohravat" do stranky, tak proste jen udelas neco jako div.append(vysledek_ajaxu)? Rekneme, ze todle by asi nemusel bejt az takovej problem. Ale co kdybys chtel s tema datama v javascriptu pracovat jako s datama? Nebo bys na to chtel / nechtel povesit nejaky eventy? Nebo mozna jeste jinak. Co kdybys ty stejny data jednou chtel zobrazit read-only a po druhe jima predvyplnit formular? (treba aby si uzivatel mohl zmenit neco ve svym profilu). Proste a jednoduse muze vypadat posilani si HTML jako zjednoduseni (a nekdy asi i je), ale jakmile se pak dodatecne rozhodnes, ze by bylo pekny s tema datama pracovat jako s datama tak mas proste smulu 8.3.2014
  • rmaslo : @kacerr: U každé datové položky se rozhoduji kde jí budu formátovat. A výsledkem by mělo být buď PHP anebo (XOR) JS. Pokud PHP tak není problém. Pokud náhodu vyjde, že je nutné JS tak mám dvě možnosti: 1. Bez JS nejsou vidět (nějaký nedůležitý data) 2. Bez JS jsou v "zákldním tvaru" a JS to dotáhne (třeba zvýraznění syntaxe na klientovi, wysiwyg editor a další dekorace). V tom případě beru data přímo ze stránky. Ale tomu abych se stejného výsledku snažil docílit jak na serveru tak v browseru se vyhýbám. Obecně mi velkou většinou vyjde formátování v PHP. V podstatě ve všech těch případech cos popsal bych je formátoval na serveru (různý tvary článku, RO/RW form) 8.3.2014

Pro zobrazení všech 5 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.