ugrás a tartalomhoz

MVC tervezési minta a gyakorlatban

Max Logan · 2008. Jan. 15. (K), 12.44
Most tervezek egy komplexebb webalkalmazást és gondoltam, hogy utánajárok az MVC tervezési mintának.

Addig megvagyok, hogy van a controller, ami lényegében megmondja, hogy mit lehet csinálni a modellel a view pedig megjeleníti az adatokat.

Vegyünk egy konkrét példát:

Adott egy modul, ami a megrendelő feladást hivatott elvégezni. Ha jól értem, akkor a user kitölti a megrendelőlapot, majd post-olja az adatokat. Ekkor a front controller (index.php) azt mondja, hogy ok, ez a kérés megy a megrendelő modulhoz. A megrendelő modul tudja, hogy a kapott adatokat checkolni kell, tehát van egy adatellenőrző funkció.

Ami jelen esetben nekem még nem tiszta, hogy az adatellenőrzést végző rész az controller vagy action? (művelet: felhasználó post-ol, adatokon formai ellenőrzés végrehajtása, ha minden ok, akkor átadja az adatokat mentésre)

Ha ellenőrizve vannak az adatok, akkor mentésre kerül a megrendelés. Ez egy SOAP kérésként valósul meg. Ebben az esetben a SAOP kérés összeállítása az action vagy view? (művelet: a formailag helyes adatok mentése)
 
1

MVC

rrd · 2008. Jan. 15. (K), 13.24
Szerintem úgy fog nálad a helyére kerülni, hogy mi micsoda és hova való, ha megnézel egy keretrendszert ami MVC-t használ. A CakePHP ilyen, nézz bele, és a kérdéseid 95%-a megválaszolódik.
2

action, view

Drawain · 2008. Jan. 15. (K), 13.29
Szia!

Az action mint olyan, a controller része, vagyis a controller hajtja végre az action-t. A view semmi más, csak egy minta az oldal felépítésére, ebben nem történik semmi feldolgozás, csak kiírás a felhasználó felé. A model pedig a háttérben van, ilyen pl egy adatbázis absztrakciós réteg, de ezt igazából a controllerben használod fel (a modern mvc framework-ök már adatbázisból generálják a modelt, illetve tartalmaznak a legismertebb adatbázisokhoz valamilyen egyszerűsítő rendszert, pl. ORM-t, így itt semmit nem kell programozni). Nagyon leegyszerűsítve a dolgot, amibe programozni kell, adatbázist lekérdezéseket, fájl írásokat, stb végrehajtani, az mind a controller része, a megjelenítés pedig a view része (ez az adatokkal nem operál, mindent a controllertől kap, pl a lekérdezés eredményét egy tömbben).

Tudom ajánlani az elte php speciének oldalát, illetve ugyanitt egy egyszerű mvc rendszer felépítését bemutató példa.

Mielőtt az ember MVC tervezési mintával kezdene el dolgozni, szerintem érdemes ránézni a népszerű MVC-s keretrendszerekre, mint amilyen a Symfony és a CakePHP.
3

Az elvet értem, de a konkrétumokat nem

Max Logan · 2008. Jan. 15. (K), 15.17
A linkelt ELTE-s doksit megtaláltam. Kicsit megvilágosított, de sok kérdést hagyott maga után.

Nem igazán tudom eldönteni, hogy adott esetben mi hova tartozik. A view ugye az adatok megjelenítése. Egy megrendelő adataiból pdf készítése, az most view vagy action?

Az adatok validálása egy action vagy a model feladata? És a model egyáltalán micsoda, az adat amit DB-ből lekérek vagy egy egész DB kezelő réteg és a model kimenete az adat?

Az adatok mentése a controller vagy a model feladata? Tehát egy action végzi a mentést (sql_query) vagy a model-nek van egy olyan metódusa, ami a mentést végzi? A model egy adatcsokorként fogható fel vagy egy objektumként, aminek vannak tulajdonságai és metódusai. És ebből következően a tulajdonságokhoz a metódusokon keresztül fér hozzá a controller?

Szóval nem igazán tiszta, hogy a model az most csak az adat, vagy az adat és az adat elérését megvalósító műveletek együttese? Mert ha az utóbbi, akkor a model nem pusztán az amin műveletet végzünk, hanem a művelet már maga (ezt most jól megaszontam, de remélem érthető, hogy mit akarok mondani) amit elvileg a controllernek kellene csinálni, mivel ő végzi a feladatokat az adatokon.

A controller valójában micsoda? Mert ha az action a controller része - adott esetben egy metódusa -, akkor hogyan kerül meghívásra a controller? Vagy a controller, az csak egy osztály és az action-ök a metódusok? De akkor minek nevezzük azt a részt ami meghívja az action-öket, ha a controller valójában csak egy tároló?
4

konkrétumok

Drawain · 2008. Jan. 15. (K), 16.08
Konkrétumok hmm.. Hát akkor Symfony-s példákkal élve:

A view csak és kizárólag a felhasználó böngészője felé küldött megjelenési minta. A pdf készítés így a controller feladata (pl. Symfony DomPDF).

Az adatok validálása megintcsak a controller feladata, még akkor is ha a framework mondjuk a model definiálásánál ad lehetőséget ennek beállítására (ekkor hozzágenerálja a control-hoz a megfelelő validáló függvényeket).

Egyébként szerintem akkor könnyű megérteni, ha egy egyszerű (egyszerűsített) példát nézünk Symfony-ban:

Help oldal lekérdezése (máshol mondjuk help.php-nak felel meg :))

1. index.php-nak megy a kérés a help oldal meghívására
2. index.php futtatja a controller executeHelp() függvényét
3. executeHelp() függvény lekérdez az adatbázisból néhány infót (az adatbázisból lekérdezéshez a model adatbázislekérdező függvényeit használja, a biztonsággal, pl. injection-ök elleni védelemmel, nem foglalkozik, a modelbe ez szépen be van építve)
4. executeHelp() a lekérdezett információt beteszi néhány változóba, fogadja mondjuk a post és get adatokat, ezeket is változókba teszi és az egészet átdobja a viewnak, ami az átadott változók segítségével megjeleníti az oldalt
5. ha az oldalon van mondjuk egy "pdf generálása a helpből" link, akkor az egy másik action-re mutat (máshol mondjuk pdf.php?out=help")

6. erre kattintva megint az index.php kapja el a kérést, átirányítja az executePdf() action felé az egészet
7. executePdf() legyártja a pdf-et és pdf kimenettel tér vissza (a pdf tartalmát megkaphatta mondjuk postolt adatként a help oldalról; vagy újra lekérdezhette maga is az adatokat; esetleg egy view sémája alapján gyártja)



Szerintem segíthet az ha megnézed a Symfony book model-ről és view-ról szóló fejezeteit, akár csak a főcímeket. Ez sokat elárul, hogy mi van az egyes rétegekben. Minden más a controllerben van, arra a könyv több fejezetben tér ki külön.
5

Alakul

Max Logan · 2008. Jan. 15. (K), 16.42
Akkor a model valójában az adatelérési API (lekérés, módosítás, törlés, létrehozás), amit hivogat a controller, azon belül az action. A controller valósítja meg az üzleti logikát, aminek a részfolyamatait nevezzük action-nek. A felhasználó felé történő adatkiírást pedig a modell álltal szolgáltatott adatok (és egyéb adatok) alapján a view jeleníti meg.

Jól látom a helyzetet?
6

mvc

Drawain · 2008. Jan. 15. (K), 17.54
Nagyjából igen :) Persze lehetnek átfedések, ez az egész csak ajánlás, a frameworkok között is vannak eltérések.
7

Hat,

zmb · 2008. Jan. 15. (K), 21.37
nem illik controllerbe belekodolni az uzleti logikat. A pattern azt mondja ki, hogy a controller felelosege a felhasznaloi input fogadasa, a modell ertesitese az esetleges valtozasokrol. A mai keretrendszerek altalaban a front controller patternt valositjak meg, ami annyiban kulonbozik az mvc-tol, hogy:
  • a frontcontoller delegalja a kerest az actionok fele
  • a frontcontoller vegzi el azokat a muveleteket, amit minden esetben el kell vegezni (felhasznalo hitelesites, view renderelese, view dekoracio, stb)

Ezen kivul meg ezeknek a rendszereknek lenyeges kulonbsege a klasszikus mvc-hez kepest, hogy mig utobbi egy haromszoget kepez a kapcsolatokbol (m - v, v - c, c - m), addig az elobbiek nem (jellemzoen: m - c - v).

A tapasztalat, es szokas alapjan a kovetkezoket lehet javasolni:
A view egyeduli feladata - ahogy masok is irtak - , hogy a kapott adatokbol (fontos, hogy kapott, nem pedig szerzett) keszitsen valamilyen kimenetet (html, pdf, jpg, xml, fustjel, stb).

Az controller dolga a felhasznalo keres fogadasa, a keres validalasa (rossz adatok eseten hibajelzes), esetleg az adatokat olyan formara hozni, hogy az uzleti retegnek megfelelo legyen, a keres alapjan az uzleti reteg utasitasa a muvelet vegrehajtasara (az esetleges hibak kezelese, visszajelzes a felhasznalo fele), es vegul az uzleti retegtol kapott adatokat tovabbitani a view fele. Osszegezve: adat ellenorzes, es keres delegalas a dolga.

Vegul a model dolga a rendszer megvalositasa, magyaran o az uzleti reteg, az uzleti logika. Nincs semmi eloiras, hogy milyen formaban kell adatokat prezentalnia, lehet az valami eredmeny halmaz szeru dolog, de lehet objektum is. Fontos megjegyezni, hogy az uzleti logikaban nem szerencses olyan kodot elhelyezni, ami arra szamit, hogy weben lesz hasznalva (gyk: semmi request objektum, v hasonlok). Majd a controller szepen transzformalja a keresek adatait olyan formara, ami az uzleti retegnek jo. Meg egy gondolat a modelhez: celszeru funkcionalis egysegeket kepezni, amiket egy objektummal (uzleti homlokzat) prezentalunk. Mindenki (akar mas ilyen funkcionalis egyseg is) csak ezen a homlokzaton keresztul kommunikalhat ezzel a funkcionalis egyseggel. Ezzel egyreszt elerjuk azt, hogy a controller kodja tiszta lesz, masreszt lazulnak a kotesek a programban, ami konnyebb modosithatosagot, konnyebb hibajavitast vonz magaval.
8

Bonyolódunk :-)

Max Logan · 2008. Jan. 15. (K), 22.12
Tehát ha jól értem, akkor a klasszikus MVC-ben a legvastagabb réteg a model. A controller-nek csak az adatok befogadásáról, validálásáról és a model felé való továbbításról kellene gondoskodni. A model végez mindent. Majd a view csak és kizárólag adatmegjelenítésért felel (legyen az bármilyen megjelenési forma).

Ezzel szemben - azt mondod - a mai keretrendszerekben a controller lesz a legvastagabb réteg, mert az egyes alfunkciókat action-ök személyében valósítja meg és a model-t csak adathozzáférésként használja.

Nos a kettő közül melyik a jobb? Melyiket érdemes használni? Eldönthető-e, hogy jobb-e egyik a másiknál vagy ez a programozó hozzáállásán múlik, hogy neki mi a szimpatikusabb?

A különbség ott látszik, hogy Drawain megoldásában a PDF-generálás action, míg a klasszikus MVC szerint (ha jól értettem) ez view, mert adatmegjelenítés.

UpDate:

Ha jól értem a két megközelítés között a különbséget, akkor:

Klasszikus MVC:

A SOAP kérés küldése a felhasználó által megadott adatok alapján (megrendelő feladás) a model feladata.

Front controller:


A SOAP kérés a controller egy action-je.
9

Nos,

zmb · 2008. Jan. 15. (K), 22.49
en azon a velemenyen vagyok hogy az uzleti funkciokat a modelnek kell megvalositania. Ahogy talan irtam is volt a modelt az uzleti reteg gyakorlatilag prezenetalja. Talan konnyen belathato, hogyha irsz egy publikus weboldat, es hozza adminisztrativ feluletet, akkor celszeru a tenyleges uzleti funkciokat egyszer megirni, es a kulonbozo akciokban (publikus oldal, adminisztrativ oldal) ezeket hivogatni. Valami egyszeru pelda, egy forum topic megjelenitese:
Publikus oldal
  • Van egy view, ami valamilyen formaban megjeleniti a topichoz tartozo hozzaszolasokat (ezt majd a controller adja), es alatta egy beviteli mezo az uj posthoz (mint pl itt, weblavoron)
  • Van egy action, ami mast nem csinal, csak a keresbol kihamozza a topic azonositojat (ellenorzi, h telleg csak egy szam), elkeri egy Forum (o itt a model) objektumtol az azonositohoz tartozo hozzaszolok listajat, majd ezt odaadja a viewnak
  • Van egy masik action, ami az esetleges uj postokat hamozza ki a keresbol, ez dobja tovabb a Forum objektumnak mentes celjabol (nem reszleteznem most)
  • Van egy Forum objektumunk, ami prezentalja a forumot (o a model). Van nekie egy muvelete amivel egy topic hozzaszolasait szedi le. Ehhez a kovetkezo lepeseket teszi (csak hogy kicsit bonyolultabb legyen). Odafordul a Cache objektumhoz (ami most legyen egy memcache implementacio), hogy van-e benne, ilyen azonositoju hozzaszolas lista. Ha nincs, akkor odafordul az adatbazishoz, es elkeri a megadott azonositoju hozzaszolas listat. Ha itt se talalja, akkor hibat valt ki (nincs ilyen topic).


Adminisztrativ oldal:
  • Van egy view, ami mutatja a hozzaszolasok listajat, + mindegyik mellett megjeleniti egy moderal gombot
  • Van egy action, ami hasonlo kep funkcional, mint a publikus oldalon (hozzaszolas lista)
  • Van egy masik action, ami fogad egy hozzaszolas azonositot, es szol a Forumnak, h moderalja ki a hozzaszolast (nyilvan validacio, meg ilyenek)
  • A Forum moderacio funkcioja egyresz torli a cache-bol a hozzaszolast, masreszt jelzi az adatbazisban, h moderalt hozzaszolas


A pelda nyilvan nem torekszik a tokeletessegre, csak a mogottes mentalitast probalja bemutatni. Lathato, hogy az actionok relative egyszeruek (csak 1-1 fuggveny hivas talalhato forummal kapcsolatban), a tenyleges munkat a Forum vegzi.

Nos a kettő közül melyik a jobb? Melyiket érdemes használni? Eldönthető-e, hogy jobb-e egyik a másiknál vagy ez a programozó hozzáállásán múlik, hogy neki mi a szimpatikusabb?

Termeszetesen nincs jobb. A ketto kozott nincs olyan eles hatar, mint amit en sugalltam, ugy latszik itt egy kicsit felrevezeto voltam. Mindig azt kell csinalni, amit a jozan esz megkovetel.

A különbség ott látszik, hogy Drawain megoldásában a PDF-generálás action, míg a klasszikus MVC szerint (ha jól értettem) ez view, mert adatmegjelenítés.

Igen, en azon a velemenyen vagyok, hogy a PDF kimenet letrehozasa kizarolag a view feladata, a controllernek ehhez semmi koze. Latvanyos pelda erre a Spring MVC, aminel csupan konfiguracio segitsegevel valtogathatom a kulonbozo view megvalositasok. Ehhez a rugalmassaghoz viszont szukseges, hogy a controller a view-al kapcsolatban csak annyit varjon el, hogy a megadott adatokat fogadja.

Klasszikus MVC:

A SOAP kérés küldése a felhasználó által megadott adatok alapján (megrendelő feladás) a model feladata.

Front controller:

A SOAP kérés a controller egy action-je.

Nem, asszem altalaban a model feladata lehet egy SOAP keres elkuldese, bar egyertelmu kijelentest nem szeretnek tennek. Lehet olyan faramuci megoldas, hogy az akcio fogad egy valamilyen kerest, es azt a kerest SOAP-al tovabbitja valahova mashova.

Ajanlom figyelmedbe a kovetkezo ket linket:


Ahogy korabban irtam, nincs olyan eles hatar, mint amit te sejtesz.
17

Publikus vs adminisztratív

Max Logan · 2008. Jan. 16. (Sze), 15.44
A publikus és adminisztratív controller az ugyanaz vagy van külön publikus és adminisztratív?
18

Hat,

zmb · 2008. Jan. 16. (Sze), 16.59
en itt most a symfony-fele elkepzeles alapjan mondtam. A symfony aztat csinalja, hogy van egy kozos model (o neki a model a Propel), es vannak alkalmazasok (admin felulet, publikus felulet, stb), ami ala tartoznak modulok (forum, hirek), az ala pedig az akciok (uj post, uj hir).
10

nem elég precíz

Drawain · 2008. Jan. 15. (K), 22.51
Elnézést, ha nem voltam elég precíz, valóban nem tanulmányoztam ilyen mértékben az MVC-k elméleti hátterét, csak néhány példa és a Symfony alapján mozgok a témában, szóval amit én mondtam, az konkrétan a Symfony-ban van így, mint MVC rendszerben.
Itt, a view réteg gyakorlatilag template fájlokból áll, így nem végez konkrét számítási feladatot, ami pl egy pdf generálásnál jóljön - itt a controller action-jében valósítjuk meg.
A model pedig egy absztrakciós réteg, hátteret és alapfüggvényeket képez a feldolgozás során a web-alkalmazás teljes adatállományához (itt pl olyan függvények adhatóak meg, hogy az adatbázisból kiolvasott Vezeték- és Keresztnév páros a Név függvényhívásra Vezeték+Keresztnév formában adódjon át a controllernek).

A SOAP kérés megvalósítása, mivel egy adatcseréről van szó, a model feladata.
11

Összefoglalnám

Max Logan · 2008. Jan. 15. (K), 23.22
Nos, akkor az eddigiek alapján:

VIEW
- Adatokat vár
- A kapott adatokat megjeleníti

Van egy bemenete és egy kimenete, de a dobozban semmi művelet nem történik (csak az adat megjelenítéséhez szükséges műveletek, a model-nek közvetlenül nem ad parancsot adatmanipulációra).

CONTROLLER
- User-től adatokat kap
- User-től "parancsot" kap (public action)
- Ha szükséges, a kapott adatokat validálja (private action)
- MODEL-nek megmondja, hogy mi a parancs (az adatokat átadja megfelelő formában) (private action)
- MODEL-től kérhet adatokat (private action)
- VIEW-nak odaadja a MODEL által szolgálltatott (és egyéb) adatokat (private action)

Van egy bemenete, ahol adatokat és parancsot kap. Kétirányú kommunikáció a MODEL-lel. Egyirányú kommunikáció a VIEW-val.

MODEL
- Közvetlen hozzáférése van az adatokhoz
- Rendelkezik műveletekkel, melyeket az adatokon hajt végre
- Adatokat szolgáltat megfelelő formában
- Van egy fix interface-e, amin keresztül kommunikál vele a CONTROLLER

Közvetlenül hozzáfér az adatokhoz (DB kezelés, stb.), oda-vissza kommunikál a CONTROLLER-rel.


Legvastagabb réteg a MODEL, ő dolgozik a CONTROLLER dirigál a VIEW pedig infót ad a munkáról.
13

Kis pontositas

zmb · 2008. Jan. 16. (Sze), 09.51
Igen, korulbelul ezt lehet mondani. Annyit meg hozzafuznek, hogy a controller - model kommunikacio egyiranyu abbol a szempontbol, hogy a controller kezdmenyez, a model nem. Tehat a controller tud (fugg) modelrol, mig a model nem tud (nem fugg) a controllertol. Amennyiben megis szukseg forditott iranyra (tehat a model akarja ertesiteni a controllert), akkor erdemes a modelnek esemenyeket kivaltani, es a controllernek ezekre az esemenyekre feliratkozni.
14

Az adatfolyam kétirányú

Max Logan · 2008. Jan. 16. (Sze), 09.58
A kétirányú kommunikációt úgy értettem, hogy a controller adatokat küld a model-nek (egyik irány), valamint adatokat kér a modeltől (másik irány). Tehát az adatfolyam kétírányú.
21

BBCode értelmezőt hova?

Max Logan · 2008. Jan. 17. (Cs), 21.22
Egy BBCode értelmező hova kerüljön? Legyen egy külön egység és a controller a model-től kapott adatokat átnyomja a BBCode értelmezőn, majd így adja oda a view-nak? Vagy inkább a view egy helper-je legyen?

UpDate: Én a helper-re szavazok. Kinek mi a véleménye?
22

Nézet

Joó Ádám · 2008. Jan. 17. (Cs), 23.28
Mindenképp nézet legyen; ugyanaz a BBCode másképp dolgozandó fel HTML és másképp PDF kimeneten.
12

Tényleg nem

Joó Ádám · 2008. Jan. 16. (Sze), 00.47
Sokan hiszik azt, hogy a nézet lényege az, hogy nem tartalmaz programkódot, holott ez egyáltalán nem igaz, sokszor még többet tartalmaznak, mint a vezérlő.
A PDF esetében a vezérlőnek csak annyit szabad tennie, hogy kiolvassa a modellből az adatot és azt továbbadja a nézetnek, legyen az bármi is. Ha egy PDF nézetről van szó, akkor az – minden szükséges számítással együtt – létrehoz egy kimenetet.
Én most Zend Frameworkben úgy dolgozok, hogy elég létrehoznom egy új nézet fájlt pdf kiterjesztéssel és máris elérhető az adott művelet PDF kimenettel.
19

Megjelenítési logika

Heilig Szabolcs · 2008. Jan. 16. (Sze), 19.26
Igen, a view-ben lévő programkód nem hiba. Gondolj például egy listára, ahol minden második elemet más szürke háttérrel akarsz megjeleníteni. Ha nem a view rétegben valósítanád ezt meg, akkor sérül a rendszered MVC szeparáltsága, hiszen a controller vagy a model réteg határozná meg direkt vagy css class-el a háttérszínt. Ami hiba, hiszen egy arculatváltás esetén nem csak a view-ban kell kotorni.
20

Hol vastag

Heilig Szabolcs · 2008. Jan. 16. (Sze), 19.35
Szvsz az a jó, ha mind az alacsony szintű adatmanipulálásért felelős model, mind a controller viszonylag elég vékony. Kicsit ellentmondásos, de mindjárt feloldom. Elvileg a model feladata az egyszerű adatkezelés. "Vedd elő, tedd el, számold meg". A controllerben sem szabad elvileg többnek lennie, mint az alapvető vezérlési logikának. Inputok begyűjtése ellenőrzése, megfelelő view kiválasztása és adatokkal ellátása. Viszont van, hogy egy-egy modul esetében túl sok a logika. Bonyolult számításokat kell végezni, vagy csak egyszerűen sok szempont alapján kell összetett feladatokat végezni. Ilyenkor érdemes ezt a fajta logikát kiemelni és külön osztályokban megvalósítani. Szvsz. Ezáltal a controller és az alacsony szintű model réteg is áttekinthető marad. Fontos viszont, hogy ez esetben a kiemelt logikának nem szabad kontroller szerepet felvennie, azaz az ő feladata kizárólag a modell alapján dolgozni és adatokat, struktúrákat visszaadni a kontroller részére. Az majd dönt felőlük.
15

Több view

Max Logan · 2008. Jan. 16. (Sze), 14.45
Ha adott esetben egy model-hez több view tartozik, akkor több view objektum legyen vagy legyen egy view objektum és annak több metódusa, amik megfelelnek az egyes nézeteknek (pl. create_HTML, create_PDF, create_RSS, stb.)?
16

Mivel

zmb · 2008. Jan. 16. (Sze), 15.01
egy view egy megjelenest reprezental, ezert celszeru mindegyik megjeleniteshez kulon objektumot csinalni (Os View objektumbol szarmaztatni a PDFView-t, a HTMLView-t, az RSSView-t, stb.). Ugye, emiatt konnyebb lehet uj megjelenest belegyurni a rendszerber
23

Az oldal összeállítása, de hol?

Max Logan · 2008. Jan. 23. (Sze), 00.22
Adott egy index.php, ami delegálja a felhasználói kéréseket. Adott egy layout generáló funkció, ami a user-nek adja a kész oldalt. Adott egy-egy modul, azon belül a funkcionalitás MVC logika szerint megvalósítva (valójában még nincsen, ez még csak elmélet). A delegált kérést a controller irányítja, model-lel kommunikál, majd a végén a view-nak adja az adatokat, ami a megfelelő formában megjeleníti.

A probléma itt kezdődik. Tegyük fel, hogy egy felhasználói kérésre adandó az oldal tartalmi részére egy táblázat.

Ekkor:
  1. Kérés a felhasználótól
  2. Vezérlés átkerül az adott modul-hoz
  3. Controller dirigiál
  4. View visszaadja a táblázatot
  5. index.php végén a layout generáló beilleszti a tartalmi részre a táblázatot

Ez mindaddig ok, amíg az adatokat HTML-ként kell visszaadni. A gond akkor van, ha pl. egy XML-t kell adni a user-nek és csak azt, nem kell layout generálás.

Ha nem egy HTML kimenet lesz a view eredménye, hanem egy XML, PDF, CSV, stb. akkor én jelen pillanatban két megoldást látok:
  1. A layout összeállítás nem a program végén történik meg, hanem az egyes modulokban.

    Ennek hátránya, hogy ha változik pl. a layout generálást végző osztály (változó) neve, akkor minden egyes modulban át kell írni. Előnye, hogy csak azon felhasználói kéréseknél adom ki a layout-ot ahol tényleg az oldalt kell megjeleníteni.

  2. A layout összeállítása a program végén történik, de az XML, stb. kiírás után megszakítom a program futását egy laza exit() hívással. Ekkor ugye a program vége nem fut le. Ez nem tűnik túl barátságos megoldásnak.

Tehát a kérdésem az, hogy a kettő közül melyik a jobb megközelítés, esetleg van-e egy (vagy több) jó (jobb) alternatíva?
24

Kimenet, templatezés

janoszen · 2008. Jan. 23. (Sze), 08.56
Ez nem tűnik nekem egy hatalmas nagy problémának. Az MVC logika V részében templatezést használsz és ha jól van megírva a C-d, akkor különbséget tud tenni URL alapján, hogy mit is kell pontosan kiszolgálni. Egyszerűen csak a megfelelő templatet rántod be, legyen az osztályokkal megvalósított vagy éppen Smarty.

Nyilván, nem tudod egy nagy MVC-vel lefedni az egész programlogikát. Én úgy képzelem el, hogy elsőként ki kell találnod, mit is szeretnél pontosan. Azaz, az URL alapján elő kell vadásznod, melyik controllert is szeretnéd Te most használni (blog, nyitólap, stb. vagy ahogy tetszik). Ez a controller (kis MVC) találja majd ki, hogy milyen kimenetet kell adni a viewnak és vadássza össze a megfelelő model-eket.

Tovább is bonthatod, betöltesz egy konfigurációs állományt, ami meghatározza, milyen még kissebb MVC-ket kell berántani (legújabb fórum hozzászólások, legújabb bejegyzések, szöveges tartalom, stb.) és ezeknek megint csak lehet egy kis V-jük, hogy a saját megjelenésüket szabályozzák. Innentől kezdve pedig egy struktúraként kezeled az egészet, nem egy nagy monolitikus rendszerként. Azaz, földaraboltad ehető részekre a problémát.
25

Elképezlés

Max Logan · 2008. Jan. 23. (Sze), 09.29
Ez nem tűnik nekem egy hatalmas nagy problémának. Az MVC logika V részében templatezést használsz és ha jól van megírva a C-d, akkor különbséget tud tenni URL alapján, hogy mit is kell pontosan kiszolgálni. Egyszerűen csak a megfelelő templatet rántod be, legyen az osztályokkal megvalósított vagy éppen Smarty.

Ez eddig tiszta sor.

Nyilván, nem tudod egy nagy MVC-vel lefedni az egész programlogikát. Én úgy képzelem el, hogy elsőként ki kell találnod, mit is szeretnél pontosan. Azaz, az URL alapján elő kell vadásznod, melyik controllert is szeretnéd Te most használni (blog, nyitólap, stb. vagy ahogy tetszik).

Ezt csinálja a Front Controller az index.php-ben, ami behúzza a megfelelő modul-t (amiben az MVC logika van).

Ez a controller (kis MVC) találja majd ki, hogy milyen kimenetet kell adni a viewnak és vadássza össze a megfelelő model-eket.

Ez is tiszta sor, mert az felhasználói kéréstől függően lesz kiválasztva a view (a felhasználói kéréshez kapcsolódó view, pl. egy táblázat generálása).


Viszont a fent említett probléma él, tehát a program végén állítsam össze az oldalt, ha kell (a modul view-ja egy változóba tolja a kimenetet, ami aztán a layout-ba kerül behelyettesítésre), vagy az egyes modulokban és akkor tudom szabályozni, hogy most kell html layout-ot megjeleníteni vagy sem (az egyes action-ökben). Az exit()-es megoldása azért nem tűnik barátságosnak, mert ha az action végén megszakítom a script futását, akkor adott esetben a program végén található kód nem fut le.
26

Nézetben vagy különböző elrendezések

Joó Ádám · 2008. Jan. 23. (Sze), 22.14
Eldöntheted, hogy alapjáraton be van-e kapcsolva az elrendezés (layout). Mivel az esetek nagy részében azért HTML lesz a kimenet, érdemes bekapcsolni. Ha mégsincs rá szükség, akkor a nézetből kapcsold ki (kell írnod egy tagfüggvényt, amit meghívva ez megtörténik).
Azonban sokkal inkább követi a minta szellemiségét, ha elrendezésből is többfélét gyártasz – ebben az esetben lesz egy layout.html-ed és egy layout.xml-ed, és ezt is a paraméter alapján szolgálod ki. Ha pedig adott típusú nézethez nincs elrendezés, akkor nem szolgálsz ki.
27

Kikapcs

Max Logan · 2008. Jan. 24. (Cs), 00.09
Eldöntheted, hogy alapjáraton be van-e kapcsolva az elrendezés (layout). Mivel az esetek nagy részében azért HTML lesz a kimenet, érdemes bekapcsolni. Ha mégsincs rá szükség, akkor a nézetből kapcsold ki (kell írnod egy tagfüggvényt, amit meghívva ez megtörténik).
Hm, ez nem is rossz ötlet.

Azonban sokkal inkább követi a minta szellemiségét, ha elrendezésből is többfélét gyártasz – ebben az esetben lesz egy layout.html-ed és egy layout.xml-ed, és ezt is a paraméter alapján szolgálod ki. Ha pedig adott típusú nézethez nincs elrendezés, akkor nem szolgálsz ki.

Ez nem teljesen tiszta.

Az elképzelésem az, hogy van egy template engine (ez jelen esetben saját megoldás lesz), amivel megvalósítom a layout kezelést. Tehát indul a script, inicializálja a layout objektumot, majd beilleszti az oldal egyes részeit (html head, menü, stb.) a template-be (tpl változó hozzárendelések). Ezután a vezérlés átkerül az adott modulhoz. Ott a controller dirigál, adatokat kér a model-től, majd odaadja a view-nak. A view visszaad egy string-et (html generálás esetén), amit megkap a script végén a layout objektum és végül megjeleníti az oldalt. A fenti layout kikapcs fonalon elindulva, ha XML-t kell generálni, akkor
$layout -> render = false;
a view kimenetre küldésekor, ergó csak az XML kerül a kiementre, a layout nem.
28

Konkrétabban

Joó Ádám · 2008. Jan. 24. (Cs), 01.03
Ahogy én csinálom:
  1. Az index.php-hoz befut a kérés
  2. Az elülső vezérlő (front controller) meghívja a kért műveletet (action)
  3. A művelet kapcsolatba lép a modellel, majd az eredmény egy nézet objektumba kerül
  4. Egy URL paraméter alapján eldől, hogy milyen nézetet kell kiszolgálni (HTML, JSON, XML, PDF, txt…), a nézetobjektum pedig átadásra kerül a megfelelő sablonnak (pl. action.html, action.xml)
  5. Ha van ilyen típusú elrendezés (layout.html, layout.xml stb.), akkor feldolgozom azt is és a művelettől visszakapott stringet adott helyre beillesztem (egyébként marad önmagában)
  6. A kimenetet elküldöm a böngészőnek
29

MVC V nélkül

Max Logan · 2008. Feb. 11. (H), 19.26
Az nem hibás megközelítés, ha egy adott probléma megoldásánál az MVC mintából kimarad a VIEW?

Hogy konkrét legyek, egy Session Manager-t csinálnok, de nem igazán van szükség VIEW-ra, mert ami a felhasználó felé megy infó, azt a Session Manager-t használó modul generálja (már amikor szükség van infó küldésre).
30

Re: MVC V nélkül

zmb · 2008. Feb. 11. (H), 21.18
Az MVC egy tervezesi minta ami egy problemara ad egy megoldast. Ezek a mintak nem arrol szolnak, hogy butan egymasra dobalod, es oromkodsz, h miket tudsz, hanem segit objektum kozpontu szemlelet kialakitasaban. Tehat, ha van neked egy problemad, es ugy erzed, hogy a problema megoldasahoz kell egy olyan objektum, ami az adatokat, es egy olyan objektum, ami a vezerlest (folyamatot) valositja meg, nosza, hozd letre oket. Veletlenul hasonlit a dolog az MVC-re? Hat akkor mi van. Ha megnezel mas mintakat, ott is lehet ilyet latni. Pl. Abstract factory - Adapter paros. Az Adapter segit kulonbozo - eltero -feluletek osszehozasaban, olyan modon, hogy az egyik feluleten jott hivast delegalja egy masikra. Az Abstract factory egy konkret megvalositasa is pont ezt csinalja. De ugyanigy lehet parositani a Template method - Abstract factory parost.

Na, sok a rizsa a lenyeg: nem kovetsz el eretnekseget, ha csak nincs view.
31

Miért nem MVDC?

inf3rno · 2009. Ápr. 15. (Sze), 01.54
Én azt nem értem, hogy a model-t, avagy üzleti logikát miért nem választották le az adatkezelésről?

Mondok egy példát:

Vannak júzerek, ezeket listázzuk. Bizonyos júzereken módosításokat végzünk. Ezeket a módosított elemeket összegyűjtük egy tömbbe, és továbbítjuk a hozzájuk tartozó dao-nak, ami elvégzi a módosításokat.

Ehhez van egy Controller, ami továbbítja a Model-nek a módosítandókra vonatkozó adatokat. A Model ezek alapján lekéri a Data-tól a megfelelő sorokat, az egyes sorokból pedig user objektumokat készít, vagy csinálsz egy users objektumot, kinek hogy tetszik. Utána a Model meghívja az users objektumon a módosításért felelős függvényt, és átadja neki a módosítással kapcsolatos adatokat, amiket a Controllertől kapott. Az userek módosulnak, ezután a Model hívja a Data-t a módosítások mentésére.

A Data és a Model között is van egy réteg. Egyrészt erre azért van szükség, mert a Modelben használt formája és a tárolási formája az adatnak eltérő, ezért nyilván konvertálni kell. Ez úgy megy, hogy mondjuk egy user lekérésnél a Data létrehoz egy user objektumot, és ennek a setter függvényeivel beállítja a megfelelő értékeket.


Egyébként ti hova raknátok az oldalak kesselését.
Itt arra gondolok, hogy mondjuk mi van, ha a View generál egy oldalt, és azt lementitek adatbázisban, aztán a következő lekérésre már az adatbázisból olvassa ki az oldal. Ezt a cache kódot ti hova sorolnátok?

A kérdés érdekessége, hogy adatbázis lekérés(Data) mellett nincsen üzleti logika (Model), a megjelenítéshez tartozik (View), és elvileg a Controllernek kéne ellenőrizni, hogy van e az adatbázisban cache bejegyzés.

Persze erre is rá lehet erőltetni egy MVC mintát, de elvileg a kesselésnek semmi köze nincs az üzleti logikához. Szerintem úgy több értelme van, ha a Model dolgát a Controller veszi át, és ő kéri le a Data-tól az adatot, a View pedig csak egy sima echo.
Erről mi a véleményetek?
32

Best MVC Practices

Drawain · 2011. Jan. 18. (K), 00.33
Régi téma, de szerintem még mindig aktuális és máig sok vitát kavarhat. Egy linket helyeznék itt el egy jó leírásra egyenesen a Yii keretrendszer dokumentációjából, ami kellőképp egyszerűen és érthetően összefoglalja az MVC paradigmát.

Best MVC Practices
33

5 évvel később

Max Logan · 2013. Jan. 26. (Szo), 16.29
5 évvel az eredeti kérdés felvetése után ki tudom jelenteni, hogy a legtöbben rosszul állnak hozzá az MVC minta megismeréséhez. A probléma az, hogy az MVC csak egy irányadó minta, nem pedig egy követendő „törvény”, pontos használati utasítással.

Az MVC-t nagyjából úgy kell kezelni, mintha azt mondanánk, hogy autó. Az autónak is vannak jól elkülönülő részei, de hogy ki miként valósítja meg, tesz-e hozzá, vesz-e el belőle, az csakis a készítő egyedi gondolkodás(módj)ának és a megvalósítandó célnak (pl. városi, kis fogasztású autó, offroad járgány, stb.) a függvénye.
35

Az MVC egy laza elv, aminek

Joó Ádám · 2013. Jan. 26. (Szo), 20.01
Az MVC egy laza elv, aminek az egyetlen célja, hogy könnyebben karbantartható legyen a kód. Nincsen végső igazsága.
34

Egy link

Max Logan · 2013. Jan. 26. (Szo), 16.31
Egy blogbejegyzés MVC témában: Mi van az MVC tervezési mintán túl?