Přejít k navigační liště

Zdroják » PHP » Nette Framework: MVC & MVP

Nette Framework: MVC & MVP

Články PHP, Různé

Když Trygve Reenskaug v roce 1979 popsal architekturu Model–View–Controller (MVC), zapsal se do dějin programování a jeho jméno by měl znát každý vývojář na celém světě. To by mu ovšem rodiče museli dát nějaké lépe zapamatovatelné.

Letos slaví MVC kulaté výročí a zdá se, že je populárnější než kdykoliv předtím. V čem je jeho síla? A hlavně – proč jej každý chápe trošku jinak? Pro odpověď se musíme vrátit do sedmdesátých let minulého století, do doby příchodu aplikací s interaktivním uživatelským rozhraním. Byla otázka, jak takové aplikace vůbec navrhovat. Nejjednodušší cestou bylo spojit uživatelské rozhraní s logikou aplikace v jednolitý celek. Tento přístup se dodnes často používá v Delphi, ASP.NET (Web Forms) nebo PRADO.

Disclaimer: Autor článku je hlavním vývojářem frameworku Nette.

Rychle se ale ukázalo, že přímočarost tohoto řešení si vybere daň v okamžiku, kdy je potřeba část aplikace změnit, nebo když aplikace získá na složitosti. Kvůli přílišné provázanosti jsou zásahy do kódu nejen komplikované, ale ani nelze dost dobře testovat. Řešením je oddělit kód uživatelského rozhraní od kódu aplikační logiky, označovaného jako model. Samotné rozhraní lze přitom ještě rozdělit na vrstvu, která obstarává výstup na monitor (view) a vrstvu zpracovávající vstupy z klávesnice nebo myši (controller). Poznámka: v sedmdesátých letech místo monitoru, klávesnice a myši používali tuším elektronku, děrovačku a dřevěnou pramyš.

Architektura Model–View–Controller

Architektura Model–View–Controller

Model o existenci pohledu (tj. view) nebo kontroleru neví. Pohled a kontroler jsou dvojčata, děvče a chlapec. Děvče prezentuje data modelu, jak nejlépe umí, a když uživatel zareaguje, úlohu převezme chlapec a zpracovanou reakci doručí modelu. Alespoň takto se chová historicky první implementace MVC v jazyce Smalltalk-80.

Všechno je jinak

Mám pro vás překvapení: originální návrh MVC z roku 1979 (v PDF, na straně tři je dokonce skvrna od Trygveovy prakávy). Na celé věci je pikantní, že spíše než o MVC jde o MVCE, kde „E“ znamená Editor. K čemu slouží tajemný editor? Kupodivu jde o totéž, co se ve zmíněné první implementaci nazývá Controller a je dokonce společně s View reprezentován jedinou třídou. A pozor: v původním návrhu spojení mezi modelem a controller/editorem obstarává view.

Proč vás tu drtím rádobyzajímavostmi z let, kdy vaši rodiče nacvičovali spartakiádu? Historický exkurz měl ukázat, jak různorodé bylo pojetí MVC už v okamžiku vzniku. Byla to holt doba pionýrská. Nechápejte proto MVC dogmaticky! Jinak budete mít více otázek než odpovědí.

Vhodnější je MVC vnímat obecněji, jako princip mající za cíl přemostit mezeru mezi lidským mentálním modelem a modelem počítačovým, jehož ideálu zatím nebylo dosaženo. Proto se také mohou různé MVC implementace podstatně lišit. Mimochodem, Trygve Reenskaug oznámil, že problematika MVC má daleko více aspektů, než si v roce 1979 uvědomoval, a začal před pár lety pracovat na novém návrhu.

Architektura Nette Frameworku

Nette Framework prošel dlouhým vývojem, na jehož počátku byla (dnes si troufám říci) revoluční myšlenka: nechť je odkaz totéž, co zavolání funkce.

Co je pro programátora přirozenějšího, než zavolat funkci či metodu a předat jí argumenty? Cílem bylo oprostit se od uvažování v rovině URL, kde se nejprve musí nějak poskládat hypertextový odkaz, aby se poté mohl pomocí pravidel mod_rewrite ještě přeskupit a nakonec byl v cílové stránce analyzován. Zároveň jde o protipól přístupu ASP.NET, které umí na odkazy zavěsit handler.

Princip si nejlépe ukážeme na příkladu. Nevím jak vy, ale já bych si dal dobrou kávu, tak co si naprogramovat aplikaci „Automat na kávu“?

Uvnitř automatu je zásobník na suroviny a mince, tedy databáze. Zásobník je součástí modelu, jehož API bude tvořit jediná metoda buyCoffee($money) a konstanta COFFEE_PRICE určující cenu nápoje. Všimněte si, že model splňuje požadavek nezávislosti na uživatelském rozhraní a bude i snadno testovatelný. Vzhled aplikace lze měnit bez obav, že bychom museli zasáhnout do datové části nebo aplikační logiky.

class Model extends Object
{
        const COFFEE_PRICE = 10;

        public function buyCoffee($money)
        {
                if ($money < self::COFFEE_PRICE) {
                        return FALSE;
                }

                ... // uschovej peníze, vyrob kávu
                return TRUE;
        }

} 

Přístupme k uživatelské obsluze automatu (angl. vending machine). Tedy třídě, která bude přímo komunikovat s modelem a prezentovat jej v lidsky přívětivé formě. Odsud název presenter. API této třídy bude nabízet metodu pro přijetí vhozených mincí a pro vydání kávy. Zároveň bude počítat, kolik peněz již bylo vhozeno, a komunikovat s uživatelem pomocí displeje (prezentační logika).

Následující kód je nástin, jak by presenter mohl vypadat. Za chvíli jej ještě mírně upravíme.

// use NetteApplicationPresenter;

class MachinePresenter extends Presenter
{
        /**
         * Hodnota vhozených mincí.
         */
        public $money = 0;


        public function __construct()
        {
                // na displeji, který je součástí šablony, zobrazíme výzvu k vhození peněz
                $this->template->display = 'Vhoď ' . Model::COFFEE_PRICE . ' Kč';
        }


        public function insert($coin)
        {
                // zvýšíme hodnotu vhozených mincí
                $this->money += max(0, (int) $coin);

                // na displeji zobrazíme celkovou částku
                $this->template->display = $this->money . ' Kč';
        }


        public function buy()
        {
                // příkaz pro model
                $model = new Model;
                $result = $model->buyCoffee($this->money);

                if ($result) {
                        $this->money = 0; // vynulujeme částku (automat nevrací)
                        $this->template->display = 'Dobrou chuť';
                        $this->giveCoffee(); // vydáme uživateli kávu
                } else {
                        $this->template->display = 'Málo peněz';
                }
        }

}


// příklad použití
$presenter = new MachinePresenter;
$presenter->insert(5); // vložíme 5 Kč
$presenter->insert(2); // vložíme 2 Kč
$presenter->insert(2); // vložíme ještě 2 Kč
$presenter->buy(); // necháme si vydat kávu 

Zbývá nám navrhnout vizuální podobu uživatelského rozhraní. To může vypadat jako skutečný automat na kávu, vedle něhož vyskládáme obrázky mincí, které se kliknutím vhodí dovnitř. Na automat umístíme displej a tlačítko pro vydání kávy. Kromě grafiky připravíme HTML šablonu:

<body>
        <div id="machine"><!-- automat -->
                <p id="display"><?php echo htmlSpecialChars($display) ?></p>

                <a href="..."><img src="images/button.png" alt="Kup kávu" /></a>
        </div>

        <ul id="coins"><!-- mince -->
                <li><a href="..."><img src="images/coin-1.png" alt="Vhoď 1 Kč" /></a></li>
                <li><a href="..."><img src="images/coin-2.png" alt="Vhoď 2 Kč" /></a></li>
                <li><a href="..."><img src="images/coin-5.png" alt="Vhoď 5 Kč" /></a></li>
                <li><a href="..."><img src="images/coin-10.png" alt="Vhoď 10 Kč" /></a></li>
        </ul>
</body> 

Všechny odkazy zatím míří do prázdna. Jak už víte, Nette Framework chápe odkaz jako zavolání funkce. U jednotlivých odkazů tedy rovnou napíšeme, kterou z výše uvedených metod mají zavolat. Obrázek pětikoruny zavolá insert(5). Nemůže to být jednodušší. Nemuže to být přímočařejší!

Je pochopitelné, že nelze do šablony přímo psát, např.:

<a href="<?php $presenter->insert(5) ?>"><img src="images/coin-5.png" alt="Vhoď 5 Kč" /> 

protože PHP by příkaz vykonalo již při vykreslování šablony. My ho chceme vykonat až poté, co na něj uživatel klikne. Zápis proto jen mírně modifikujeme:

<a href="<?php echo $presenter->link('insert!', 5) ?>"><img src="images/coin-5.png" alt="Vhoď 5 Kč" /> 

a to je vše! Jakmile uživatel klikne na obrázek mince, zavolá se $presenter->insert(5). Nic víc nemusíme řešit!

Z bezpečnostního hlediska ale není dobré, aby bylo takto možné zavolat jakoukoliv metodu třídy MachinePresenter. Volatelné (sic) metody je potřeba nějakým způsobem označit. V úvahu připadá několik způsobů, z nichž nejschůdnější je asi prefixování, tedy přilepení klíčového slova před název metody. Pro naši situaci Nette používá prefix handle, takže metody insert() a buy() přejmenujeme na handleInsert()handleBuy().

Ještě je třeba zajistit, aby obsah proměnné $money byl trvalý, aby se nevynulovala při každém HTTP požadavku. K tomu slouží tzv. anotace  @persistent:

        /**
         * Hodnota vhozených mincí.
         * @persistent - proměnná se bude přenášet mezi HTTP požadavky
         */
        public $money = 0; 

A to je vše. Kompletní aplikaci si stáhněte, rozbalte a v prohlížeči otevřete soubor index.php, který se nachází v adresáři document_root. A dejte si kávu…

Nabízíme dobrou brazilskou kávu.

Nabízíme dobrou brazilskou kávu.

Presenter v Nette Frameworku má podobnou roli jako kontroler v MVC. Vybírá pohled (view) a předává mu model, nebo data z modelu. Udržuje stav persistentních proměnných. A především zpracovává reakce uživatele. Ty se dají rozdělit na tři typy:

  • změna pohledu (s tím jsme se v jednoduchém Automatu na kávu nesetkali)
  • změna stavu (po vhození mince)
  • příkaz modelu (po stisknutí tlačítka)
Architektura Model–View–Presenter v Nette Framework

Architektura Model–View–Presenter v Nette Framework

A co URL?

Ačkoliv Nette Framework nás zcela odstínil od úvah nad URL, neznamená to, že nemůžete jejich podobu ovlivnit. Ba právě naopak! Framework nám dává nad URL absolutní kontrolu. Jen prostě v tuto chvíli by úvahy nad jejich tvarem odváděly pozornost od skutečného úkolu. Podobu URL můžeme rozhodnout později. A bez nutnosti cokoliv měnit v samotné aplikaci.

Vychutnejte si voňavou kávu z Nette automatu, v příštím díle se k němu vrátíme a naučíme ho vařit AJAXově.


Autor článku je vývojář na volné noze, specializuje se na návrh a programování moderních webových aplikací. Pravidelně pořádá školení pro tvůrce webových aplikací, vyvíjí open-source knihovny Texy, dibi a Nette Framework.

Používáte MVC?

Komentáře

Subscribe
Upozornit na
guest
49 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
blizz.boz

david je best ma dobry flow, skills, dava dobre freestyly ma dobre produkcie proste je to pan

Abraxis

Muj problem s MVC pristupem je ten, ze casto je velmi spatna podpora aktivni komunikace ze strany modelu k view. Zni to jako paradox, ale proste se jedna o klasicky pripad, kdy treba mam v GUI tabulku s daty (ted mam na mysli klasickou, ne-webovskou aplikaci) a model je navazany at uz na databazi nebo treba zobrazuje obsah slozky. Treba ve Swingu je docela porod, aby model notifikoval (vsechny) pohledy, ze doslo ke zmene – protoze holt MVC ocekava, ze veskere zmeny modelu budou iniciovane z controlleru.

Nebo proste jenom nevim jak na to?

Anonymní

Nevim jestli jsem to pochopil spravne, ale v cem vam nevyhovuje Observer-Observable?

mike

S výhodou lze použít eventbus – model (nebo kdokoliv jiný) vyvolá událost a kdo chce ať si jí naslouchá a podle toho koná, čili jednotlivé komponenty o sobě nemusí vůbec vědět (loose coupling). Tato konkrétní implementace má i speciální podporu pro Swing, která zajišťuje doručování událostí ve správném vlákně.

Milan Čermák

Otázkou je, zda má zde popisovaná knihovna Nette nebo i Swing ve svých widgetech a view pro zpracování událostí (nebo pattern Observer) podporu.

Osobně si myslím, že v uvedeném příkladu by bylo možné Model a Presenter sloučit. Podle mého chápání MVC oba představují model. Bohužel ale postrádám právě pattern observer, který by zde měl sloužit k notifikacím View, když se změní proměnná $money. Právě proto je potřeba ručně v kodu sáhnout do template a změnit hodnotu (metoda insert).

Luboš Horáček

O tom sloučení by to nebyl zas až tak dobrá nápad, protože to je ta halvní výhoda tohoto návrhu, logika automatu je v Modelu, ale její prezentace v Prezenteru, a když budu chtít změnit například jazyk automatu, vyměním pouze prezenter a nechávám model.

Milan Čermák

Pořád ten důvod nevidím. V uvedeném případě je chování automatu natolik jednoduché, že by bez problémů šlo do vložit do třídy Prezenter. Pokud by mělo dojít ke změně, patrně bych třídu Prezented upravoval (ve vašem příkladu bych změnil patřičné texty). Pokud by šlo o větší změnu (možnost fungování automatu v různých jazycích), použil bych nějaké sofistikovanější řešení (opět na příkladu jazyka by to bylo nejspíš na bázi překladových katalogů).
Ano, rozumím, že logika fungování automatu může být složitější a bude se muset skládat z vlastních tříd a datových objektů, které mezi sebou budou komunikovat. Tyto objekty pak budou tvořit datový model, což je ale jiný pojem než Model v návrhu MVC.

Aleš Roubíček

Klasický problém programátorů. Všechno jde napsat odzhora dolů. Otázka, je, jak je to udržovatelené a znovupoužitelné. Principy dobré objektového návrhu tu nejsou pro nic za nic. ;)

Milan Čermák

Nejspíš se příliš zaobírám popsaným příkladem. Mým cílem bylo a je říct, že chování automatu, popsané v uvedeném příkladu třídou Model, je datovým modelem, což je něco jiného než "model" v definici MVC. Definici modelu splnuje třída MachinePresenter (představuje model chování automatu pro uživatele).
Problém, který pak v příkladu vidím, je těsná vazba modelu na view (metoda insert), což je přesně to, čemu se MVC model snaží vyhnout.

Borek Bernard

Model z ukázky rozhodně odpovídá definici modelu v architektuře MVC (a asi by v něm měla být i proměnná $money) a MachinePresenter je zase typickým presenterem v architektuře MVP. Podle mého názoru je ukázka v pořádku.

Jan Havrda

Nette je psane v PHP pro webove pouziti. Nacteni novych informaci bude iniciovano uzivatelskou akci v prohlizeci, o nejakem sledovani pohledu ze strany modelu nemuze byt asi rec.

Ve vseobecne rovine muze jit o problem implementace MVC, ktera, jak David naznacil, stale neni idealni. Kazdemu vyhovuje jiny styl a take proto vznika spousta MVC frameworku. Ustalena pravidla v ramci architektury mohou byt pro vyvoj aplikace omezujici a tak se casto hledaji klicky a vyjimky pro implementaci specifickych funkci. Robustni MVC systemy se sirokou skalou funkci mohou byt slozite na nauceni, jednoduche MVC systemy zase predpokladaji vetsi zasahy do kodu aplikace ze strany programatora, a tim padem i hlubsi pochopeni kodu a logiky MVC.

Karell

Mozna se ptate na metody zacinajici na fire… Napr u AbstractTableModel je napr fireTableDataChanged(), ktera notifikuje vsechny pohledy na tento model, ze se data v tabulce zmenila a maji se prekreslit.
Takze modelu predate nova data a pak zavolate fireNeco podle toho, jaky rozsah chcete obcerstvit (pokud neresite vykon, tak vzdycky vsechno :-) ) a o vic se nemusite starat. V idealnim pripade si aplikace vubec nemusi drzet odkaz na zobrazovaci tridu pote, co ji preda model, vsechno se to obstara vnitrne ve swingu.

ava

Zajimave, ale nejsou mi jasne dve veci.

Prvni vyplyva z me neznalosti NETTE frameworku. Jak je uchovavana hodnota instancni promenne $money mezi jednotlivymi kliky? Je zakodovana do URL? Jakym zpusobem je mozne ovlivnit, ktere promenne se maji uchovat a ktere ne? Jak je to s uchovavanim slozitejsich datovych struktur? (pole, slovniky, jine objekty)?

Druha otazka se tyka volby rozdeleni zodpovednosti automatu na kavu mezi model a presenter. Ocekaval bych, ze presenter ma na starosti pouze interakci mezi modelem (tj. fyzickym strojem na kafe) a uzivatelem, tj. v pripade analogie s fyzickym automatem ma prezenter roli predniho panelu s navodem k pouziti, tlacitky, mincovnikem a vydejovym okenkem, ale _nemel_ by jiz resit vnitrnosti stroje, tj. rozhodovaci logiku zda uzivateli vydat ci nevydat kafe podle toho kolik do nej bylo nahazeno penez atd, vareni kafe, uchovavani informaci o tom kolik penez je v mincovniku atd.. V objektovem modelu by podle me mel mit prezenter pouze jedinou instancni promennou, $model, ktere by posilal zpravy jako coinInserted, coffeTypeSelected, getCoffeeMakingProgress, ale veskera obsluzna logika by jiz mela byt v modelu. Pokud zacnete cpat business logiku z modelu do presenteru, veskere vyhody MVC se vytraceji.
Koukam ze to nebyla ani tak otazka, jako spis konstruktivni kritika :)

Jinak framework pusobi vcelku rozumne, dalsi maly krucek k zjednoduseni tvorby webaplikaci..

Anonymní

Ano, $money je přenášena v url. Ovlivňuje se to pomocí té anotace @persistent. Složitější objekty bych uchovával v session.

ava

Jako zásobník na mince, který uchovává informaci, kolik mincí v něm je, si lze totiž analogicky představit třeba „zásobník na písmenka s uchováváním informace“, neboli [input type=“text“]. U něj by asi nikdo neváhal, že patří do prezentační logiky.

Nevidim zadnou analogii mezi zasobnikem na mince a retezcem(„zásobníkem na písmenka s uchováváním informace“), krome toho ze oboje bude zrejme reprezentovano jako kolekce objektu.

Nevim proc bych nemel vahat jestli patri retezec umistit do prezentace nebo byznys logiky, to mi prijde jako dost dulezite a netrivialni rozhodnuti zavisle na tom co modeluji. Jinak samozrejme _vzdy_ lze dat logiku do modelu nebo do prezentace, ale v zavislosti na konkretnim pripade ma jedno nebo druhe lepsi smysl, usnadnuje nebo ztezuje porozumneni a navrh aplikace.
Se zbytkem souhlasim.

Almad

Nechci shazovat hlavní myšlenky autora, ale dispatcher na funkci (odkaz coby zavolání funkce) mělo už cherrypy 2 (http://cherrypy.org/) se kterým jsem pracoval už pár let nazpět.

A vsadil bych se, že určitě nebylo první, kdo s timhle konceptem přišel.

michal_

citace: na jehož počátku byla (dnes si troufám říci) revoluční myšlenka: nechť je odkaz totéž, co zavolání funkce.

Tohle ale mely Ruby on Rails ohodne driv.

petr

>>Tohle ale mely Ruby on Rails ohodne driv.
A co jako? Pan Grudl snad psal ze to ma Nette prvni?? Nechapem

Anonymní

Mojavi (2003) – vychazi z neho Agavi a na Agavi zaklada routing Symfony…

Anonymní

To se vubec neda s Nette srovnat. Staci se podivat jak se v Mojavi verze 2 (rok 2004) otrocky sklada URL http://www.peterrobins.co.uk/it/mojavitutorial2.html#mozTocId492691. Princip, ktery ma Nette, zacalo mit az Symfony, PRADO od verze 3.1.1 (rijen 2007) a ASP.NET MVC (listopad 2007).

Balls McLongcock

A ted mi prosimte rekni jak to delalo Nette v roce 2004 kdyz se to neda srovnavat? :)))

TanisCZ

s ASP.NET MVC jsem se nedávno dostal do styku a když jsem v něm zkoušel cvičně programovat pár miniaplikací, nemohl jsem se ubránit dojmu, že buď mohutně opisoval Nette od Asp.NET MVC a nebo naopak. Obojí je samozřejmě blbost :)

Docela by mě zajímalo, jestli je schopný se asp.net mvc v budoucnu prosadit.
Jinak Nette je skvělý kus kodu, ktery clovek neprivadi do depresi, kdyz uz musi programovat v php. Gratulace :)

v6ak

Myslím, že controleru můžou být textové popisky ukradené a že by je měl řešit view. Na čí straně je nepochopení? Nebo jsou možné oba přístupy?

Jakub Vrána

URL by mělo vyjadřovat stav aplikace a nikoliv postup, jak jsme do tohoto stavu dospěli. Stav kávomatu je vyjádřen hodnotou proměnné $money, takže URL ?money=5 by bylo v pořádku. Naproti tomu ?coin=5&do=insert vyjadřuje postup. Podle mého názoru by akce provedená na tomto URL měla přesměrovat právě na ?money=5. A to navíc odhlížím od toho, že akce mění stav aplikace, takže by měla být odesílaná metodou POST. Pokud by se hodnota $money ukládala třeba v session proměnné, tak by reload stránky vedl k nepřípustné změně tohoto stavu.

ava

No v tomhle pripade si tedy nejsem moc jisty. Jednak nevim, proc by URL melo vyjadrovat stav a ne akci, do URL si snad muzu zakodovat co chci podle toho jak se mi to hodi.. Nevim jestli je to nejaky doporuceny postup, ale v tomhle pripade znemoznuje prihazovani vice lidi do automatu (jdu si dat romanticke kafe do automatu v delvite se svym devcetem, ja mam jen petikorunu a ona taky, kafe stoji 10 tak se dohodneme ze tam kazdy hodime vsechno a pak to jeden z nas vybere a kafe vypijeme dohromady).

– Oba si nacteme stranku kde je pro klik na petikorunu vyjadren jako ?money=5
– Ona prihodi petikorunu, vygeneruje se ji stranka s klikem na petikorunu vyjadrenym jako ?money=10, bohuzel uz petikorunu nema tak ceka na me
– Ja prihodim petikorunu, ale tim jen nastavim cilovou castku zase na 5 korun, prijdu i o sveho bura a kafe si nedame protoze automat si mysli (resp. skutecne ma) pouze 5 korun, petikoruna meho devcete jakoby nebyla (ale je klidne mozne ze se ji odecetla z kapsy! pokud neni implementovan nejaky komplikovany kontrolni mechanismus kdy se ptam automatu jestli se nekam neztratily me penize..)

To asi neni stastne reseni, lepsi by v tomto pripade bylo kdyby do URL byla zakodovana akce a stav byl ulozen jinde (na serveru).

Jakub Vrána

Možná jsem se nevyjádřil srozumitelně. URL na provedení akce by samozřejmě mělo vést na ?coin=5&do=insert (lépe navíc metodou POST). Toto URL by ale nemělo v prohlížeči zůstat a mělo by uživatele přesměrovat na ?money=5 (pokud držíme stav v URL proměnné a ne třeba v session).

Ale počkejme skutečně na další díl – jak mi David objasnil, tak přesně tímhle by se tam měl zabývat.

ava

Ach tak, to jsem skutecne pochopil jinak, takto to jiz dava dobry smysl. Omlouvam se potom za offtopic prispevek (a sobe si nadavam do gorilich klitorisu ze jsem jim ztratil tolik casu misto abych zkusil vic premyslet :-)

Aleš Roubíček

Říká se tomu REST.

pubso

Ja bych mnel dotaz stran te kvalitni brazilske kavy!

MacHala

"Když Trygve Reenskaug v roce 1979 popsal architekturu Model–View–Controller (MVC), zapsal se do dějin programování a jeho jméno by měl znát každý vývojář na celém světě."

doufam, ze ho nemusi umet i vyslovit ;)

Balls McLongcock

Ja teda v "presenteru" nevidim jediny rozdil oproti controleru. Jaky je duvod pro tohle oznaceni oproti standardnimu nazvoslovi?

Borek Bernard

> Ja teda v "presenteru" nevidim jediny rozdil oproti controleru

V Nette má view úzkou vazbu na presenter. Podle mého názoru je zvolené názvosloví správné.

Balls McLongcock

Ano a taky má úzkou vazbu na model. Opravdu kvalitní odpověď.

Aleš Roubíček

Lehký nástin rozdílů mezi MVC a MVP jsem udělal tady: http://rarous.net/weblog/236-mvc-unit-testy.aspx

Borek Bernard

Zkusím to ještě jednou a trochu obšírněji:

> Ja teda v "presenteru" nevidim jediny rozdil oproti controleru

V Nette má view úzkou vazbu na presenter, čímž se liší od controlleru ve webovém MVC modelu, kde view většinou o controlleru vůbec neví. Alešův odkaz rozdíl pěkně demonstruje.

none_

Nejsem si jisty jestli si to pamatuju dobre, ale mam za to, ze na strankach autora bylo nekde napsano ze MVC = MVP (controller = presenter). Je to jenom jiny nazev…

Milan Čermák

Rozdíl zde je, alespon v chápání Controlleru podle původního návrhu. Tam bylo úkolem Controlleru přebírat události systému (stisky kláves, pohyb a klikání myší) a na jejich základě spouštět akce definované Modelem. U webových aplikací tento úkol prakticky provádí sám browser (občas za přispění javascriptu) a komunikuje s modelem pomocí URL.
Pokud použijeme tuto definici Controlleru, pak je Presenter de facto Modelem.

Aleš Roubíček

Zajímavá implikace. Bohužel nepravdivá.

Milan Čermák

Můžete být konkrétnější v čem je nepravdivá?

Borek Bernard

Dobře jste poukázal na podobnost mezi původním chápáním MVC a dnešními webovými MVC frameworky, protože ta analogie je tam opravdu velká. Nesprávně ovšem píšete, že u webových aplikací je controllerem de facto prohlížeč: webová aplikace je serverová záležitost a o nějakém prohlížeči nemá ani tušení. "Systémové události" jsou u webové aplikace v podstatě jen jednoho typu: vyvolání skriptu přes HTTP požadavek, takže controller je ve webovém MVC modelu ten kód, který tyto požadavky zpracovává.

Balls McLongcock

Takže pokud správně chápu mohl by být rozdíl v tom, že validace a zpracování requestu je prováděno v modelu?

komorniA

Mě zaujala ta vtipná hláška z perexu o jménu Trygve. Skvělý začátek prezentace.
Jméno Trygve má 6086 Norů, přičemž v celém Norsku jsou méně než tři lidi se jménem Trygve Reenskaug. Příjmení Reenskaug má 34 lidí.
Na druhé straně, i když je jméno David na žebříčku popularity na 6-7. místě (tedy hodně vysoko), tak příjmení Grudl je v Čechách zastoupeno ve 4 případech (včetně cizinců, zemřelých, nezvěstných :). Tedy méně než Reenskaugů. Ale dá se to prezentovat i tak, že jsi výjimečnější než Reenskaug :)
Každopádně ti držím palce, prezentuj, vysvětluj, zjednodušuj, přibližuj, konkretizuj.

Ksl

A ta poznámka o elektronce, děrovačce a dřevěné pramyši taky míří tak trochu vedle, jelikož pán pracoval v PARCu, a věřím, že pro zdejší čtenáře k tomu není třeba nic dodávat. :-)

Encode

Dobrý den. Je možné že jsem si toho nevšiml, ale kde je řečeno cokoliv o struktuře, bootstrapu a jiných věcech ze staženého automatu?
Ne, že bych tímto šel proti autorovi, ale rád by jsem pochopil proč volit tuto strukturu a proč máme bootstrap když to „můžu“ všechno napcat do jednoho souboru

Lucka

Co je to htmlSpecialChar­s($display)? Proč to tam je, co to zobrazí a kde je to definované? Díky

Sopta

http://jonatan.spse.pilsedu.cz/doc/php-man/function.htmlspecialchars.html

– slouží pro ošetření výstupu

Pokud jsem to dobře pochopil, s Nette teprve začínám ale myslím si:

$this->template->display = 'Vhoď ' . Model::COFFEE_PRICE . ' Kč';

Ti vytvoří pro šablonu právě tu proměnnou $display:

<?php echo htmlSpecialChars($display) ?>

Můžeš si zkusit přidat do metody buy() pod řádek

$this->template->display = 'Dobrou chuť';
$this->template->odstavec = 'Nový odstavec';

a pak do šablony přidat třeba:

<?php echo htmlSpecialChars($odstavec) ?>

Doufám, že to je správně :) nemám to odzkoušení je pul třetí a už se mi nechce otevírat PsPad :D

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.