ugrás a tartalomhoz

Business Logic hol illeszkedik az MVC-be?

janoszen · 2010. Már. 26. (P), 08.59
Mostanában kicsit el-elmaradtam a fejlesztésből. Mivel inkább a rendszergazdai oldalával foglalkoztam, sosem jutottam el odáig, hogy föltegyem a most fölteendő kérdést.

Hova fér bele az MVC modellbe a business logic nálatok? Hogy válnak szét az elemi adatbázis-műveleteket végző modellek és a magasabb szintű logikát megvalósítók (ha egyátalán)?
 
1

Röviden

deejayy · 2010. Már. 26. (P), 09.43
Röviden: én a modellbe szoktam tenni.
2

Én is. Az más kérdés hogy

dragi · 2010. Már. 26. (P), 10.23
Én is. Az más kérdés hogy esetleg többféle modellt használsz a különböző részekhez.
Pl. van Db modelled meg van Form modelled mondjuk webnél.
3

model

Szekeres Gergő · 2010. Már. 26. (P), 13.29
én a modellek esetén is egy hierarchiai tagolódást vezetek be, az első szinten az absztrakt funkciók állnak, míg az alsóbb szinteken helyezkedik ez az üzleti logika. például az egyes entitásokat az Entity abstact osztályból származtatom, ahol már implementálva van az insert, update és hasonló műveletek. A további rétegekben ezzel nem kell foglalkoznom, tisztán üzleti logikát tartalmaznak ("property"-k, objektum validáló metódusok, stb).

A controllerben lévő űzleti logika általában "spagetti" jelleget vesz, és elég körülményesé (gyakorlatilag lehetetlenné) válik az egységtesztelés is. Ráadásul pont az egységbezárást, és a kódduplikációt teszi lehetetlenné.
4

model

winston · 2010. Már. 26. (P), 13.33
Egyértelműen model-be illeszkedik, a model kb. a "business domain", ami leírja az entitás objektumok életciklusát, működését, stb. Ahogy én használom, ott a model két részre van bontva: egyszer egy primitívebb réteg (active record, orm, vagy valami hasonló), ami kb. a backend (legtöbbször db) adatstruktúráját képzi le entitásokba, és e fölött helyezkedik el az üzleti logika, ami az ennél abszraktabb és komplexebb dolgokért felelős. Az üzleti logika helyezkedik el "felül", vagyis az események (actionok) ezeket hívják.
5

Ok

janoszen · 2010. Már. 26. (P), 13.46
OK, következő kérdés: mit csináltok azokkal az üzleti logika részekkel, aminek mondjuk view-beli (ne adj Isten kliensoldali) implikációi vannak?
6

view helper

winston · 2010. Már. 26. (P), 13.58
ha jól értem, hogy mit akarsz (bár nem vagyok benne biztos), akkor View Helper tervezési mintára van szükséged. De ha mondasz konkrét példát, mondok konkrét megoldást :)
7

Átirányítások

janoszen · 2010. Már. 26. (P), 14.00
Nem konkrét feladatból adódott a kérdés, de vegyük például azt, hogy valaki bejelentkezésnél mivel azonosítja magát (OpenID, Facebook Connect, 3rd party SSO, usernév-jelszó). Nem tudom, korrekt példa-e de a bejelentkezés milyensége lehet üzleti logika kérdése is. (Tudom, szar példa.)
8

ennek az eldöntése nem a

winston · 2010. Már. 26. (P), 14.07
ennek az eldöntése nem a felületre tartozik, legfeljebb annyiban, hogy a kiválasztott authentikációs módnak (pl. egy radiobuttonnal) megfelelő form-elemeket jelenít meg js segítségéve. ezen túl már a controller-re és a model-re tartozik: a controller eldönti, hogy minek is kell történnie (routolás), és hogy ezt mi dolgozza fel (dispatchelés), ahol az adatok formailag validálásra kerülnek (ez már az action), és az, hogy milyen authentikációs üzleti logikát hívjon, az majd ott eldől. ez controller. a konkrét authentikáció (jelszó-ellenőrzés, vagy egy külső authentikációs forrás hívása, legyen akár OpenID, ldap, vagy akármi), azt meg már a model csinálja. (pont hasonlón dolgozok)
nyilván a view függhet a modeltől-üzleti logikától. ez általában a controlleren keresztül van megoldva, megfelelő template berángatással, paraméterátadással a viewnek, néha perverzebb esetekben pedig View Helperrel, ami adott esetben model-t hív. (Bár kerülendő a dolog).
ilyesmire gondoltál?
10

Igen

janoszen · 2010. Már. 27. (Szo), 00.16
Igen, ilyesmire gondoltam, bár nem érzem annyira a tisztaság-érzést a koncepcióban. ( Tudom, használjak liberót, az tisztább. :) ) Majd még gondolkozom rajta, hogy lehetne ez igazán szép.
9

bárhol

stavros · 2010. Már. 26. (P), 18.44
Attól függ, maga az mvc modell is kérdéses sok esetben (vs KISS), szerintem nem jó mindenre ráhúzni, főleg a PHP esetén, éppen ezért a bus. log. bármi lehet. Ennbetűs struktúrát bárki kitalálhat, annyi értelme persze van, hogy ez kvázi egy megállapodás "best practice", vezeti a gondolkodást, ilyen szempontból a model-be való, ha olyan a probléma, persze ez mit jelent? semmit, csak egy tag.

Inkább modulok (osztály) / alkalmazások (domain) szerint szeparálnék, sőt sql-be is raknék dolgokat, hibrid modell, az mvc-t inkább ezek alatt képzelem el, mint programozási paradigma.
11

szerintem pont a php

winston · 2010. Már. 28. (V), 13.33
szerintem pont a php webalkalmazások tipikusan olyan dolgok, amikre az mvc modell adja magát :) nyilvánvalóan a view réteg a templatek, a kigenerálandó html, ez gondolom egyértelmű, az url alapján a külöbvöző sémák (routingok) használatával pedig kiválóan leképehető controller-ekbe, actionok-be. nyilván az adatmodell (adatbázis elérések, külső, curl, soap, egyéb hívások), ezek egyszerű crud, és üzleti logika szintű kezelése pedig érezhetően a model feladata. én a "modulok" alkalmazásának sose láttam túl nagy értelmét, mert rá lehet húzni egy controller ésvagy model osztályja azt, hogy ez egy modul, de annak nem látom erejét. (persze adódhat megfelelő szituáció, ahol van létjogosultsága) ami az alkalmazásokat illeti: ez belefér az mvc-be, az alapelgondolás felénk az, hogy egy projektben lehet több alkalmazás, minden alkalmazás a saját controller-készletével dolgozik, viszont model-szinten lehetek általános model-ek, amikből az alkalmazások leszármaztathattják a saját verziójukat. így kerek egységet adnak, modellekre az alkalmazásokon belül nincs szükség, és mindennek megvan a maga helye.
12

Szia, szerintem ezt nem

virág · 2010. Már. 28. (V), 13.54
Szia Stavros,
szerintem ezt nem gondoltad át teljesen... :)
15

lehet

stavros · 2010. Már. 29. (H), 11.48
prométeusz válaszolt helyettem, pl. ha a db elérést csak tárolt függvényekkel oldom meg, ezek alatt vannak triggerek és basic bus. log. is, a view-t generálhatja js ajax json-ból is a kliensen stb.
13

Dagadt modell, sovany kontroller

imehesz · 2010. Már. 29. (H), 03.37
Hali,

az (altalaban) elfogadott irany az ugynevezett: Skinny Controller, Fat Model (Sovany kontroller, Dagadt modell)

link

Tehat amit csak lehet, a modellbe nyomsz bele.

--iM
14

Bár lehet hogy ez csak nekem

prom3theus · 2010. Már. 29. (H), 11.32
Bár lehet hogy ez csak nekem mániám, szerintem - ha nem kritikus fontosságú a teljesítmény - érdemes modelt három rétegre bontani az újrahasznosíthatóság jegyében. Eszerint a modelben kell lennie egy alacsony rétegnek, amely lehet akár maga az ORM is (a lényege, hogy részben vagy egészben elfedje a natív adatbáziselérő megoldást, szem előtt tartva a kényelmesebb/praktikusabb query szerkesztést), a következő rétegben atomi lekéréstípusok vagy lekérések szerepelnek (ezek eddig nem, vagy csak részben hordozhatóak, mivel nagyban függenek az adatbázis szerkezetétől), és erre a rétegre érdemes húzni egy olyat, ami a lehető legközelebb esik az adott probléma megoldását jelentő magasabb szintű algoritmushoz. Ebben a szemléletben a vezérlő szűri/szűrheti a bemeneteket, kimeneteket, kiértékel és szükség szerint elágaztat stb., a nézet pedig semmi mást nem végez, mint a modeltől visszakapott adatokat a nézet szerinti formátumban reprezentálja egy kimeneten (tehát a nézetben tartózkodunk a vezérlő elemek használatától - a gyakorlatban törekszünk arra, hogy csak a legszükségesebb esetekben szerepeljenek benne ciklusok, elágaztatások, értékadások - ez egyébként a nézet sebességének is jót szokott tenni, mindegy hogy templateből generált XHTML a kimenet, vagy felépített objektumból képzett JSON, XML stb.).

A lényeg szerintem - mint mindig - hogy ne ragaszkodjunk általános konvenciókhoz, hanem jó érzékkel alkalmazkodjunk a környezethez és a felmerülő (megoldandó) problémákhoz, találjuk meg a megfelelő arányt az elosztásban. Rengeteg módja lehet a bus.log. elosztásának, a hangsúly az arányokon van. Kerülhet a bus.log egy-egy része: adatbázis oldalra (tárolt eljárás/függvény), a modelbe, a vezérlőbe, a megjelenítőbe, külső szolgáltatásba stb.
17

nem véletlen

Hodicska Gergely · 2010. Már. 31. (Sze), 06.25
A lényeg szerintem - mint mindig - hogy ne ragaszkodjunk általános konvenciókhoz
Azért nem véletlenül ajánlott, hogy a kontorller az vékony legyen, és ettől szvsz nagyon nem is éri meg eltérni. Ha a kontrollered vékony és a modelled jó le van tesztelve, akkor elég jó esélye van, hogy a legtöbb hibát el tudod kapni.

Ezen kívül kb. OOP-vel is némileg ellentétes, hisz alap szabály, hogy az összetartozó dolgokat tartsd egyben, viszont ez nem teljesül, ha az üzleti logikád egy része szanaszét van szórva a kontrollerekben.

Szintén nem szerencsés, ha a kontroller validál, hisz annak a modelben a helye. Aki a modellt írja, az fogja tudni, hogy mire is kell ellenőrizni, plusz szintén az egységbe zárással ellentétes lenne, ha a kontroller végezné. Technikailag persze lehet így, de akkor a validáció szabályai a modelltől kell jöjjenek.

Nekem a következő felállás szimpatikus:
- Vannak az alap adat objektumok (ez lehet ORM, de bármi egyéb is), pusztán a perzisztáció és a puszta adat reprezentálása a feladatuk. Ezek lehetnek value objectek vagy entitások (ökölszabály szerint utóbbi, aminek van egyedi azonosítója).
- Vannak az üzleti modellt megvalósító osztályok. Ezek használják az előbbi osztályokat, plusz definiálják a velük elvégezhető műveleteket, meg az egyéb mindenfajta logikákat.
- Az előbbi réteg még kb. kicsit általános, ezért van egy újabb service réteg, ami már konkrét használati eseteket valósít meg. Ez szintén a domain model része, de ebben kb. konkrét forgatókönyvek vannak megvalósítva. Pl. user vesz valamit az oldalon: ezt csinálom, aztán emezt csinálom stb. Ezt egyik előbbi réteg beli osztályba sem érdemes tenni, mert tipikusan abban a rétegben lévő osztályok együttműködéséből áll.
A kontrollerek a 2. és 3. réteg beli osztályokat használják, és tipikusan elég vékonyak, minimális huzalozás tartozik beléjük.
18

+1

carstepPCE · 2010. Már. 31. (Sze), 09.05
teljes mértékben egyetértek
16

Workflow!

vikos · 2010. Már. 31. (Sze), 00.04
A legegyszerűbb ha az üzleti logikát mint folyamatot értelmezed ( értékesítést... stb... ).

Ha a folyamatot mint gráfot ábrázolod akkor az egyes lépések/csomópontok lesznek a view-k, köztük lévő kapcsolatot mindig a kontroller adja.

Kontoroller-t valóban érdemes minél jobban soványítani, de a folyamat irányát meghatározó lépéseket mindig érdemes oda rakni, különben nagy lesz a káosz.

A model-t mindig érdemes funkció halmaz alapján csoportokba szedni és alkalom adtán egymásra építeni. I/O műveletek, adatstruktúrák, módosító műveletek, ellenőrzések... stb...

Ezek alapján - szerintem - ki lehet mondani, hogy a kontroller teljes egészében üzleti logikához kapcsolódik, a model-nek pedig részei.
19

Szerintem :)

Crystal · 2010. Ápr. 6. (K), 16.44
Stravod írta fentebb, hogy nem feltétlenül érdemes az MVC modellt a klasszikus értelemben használni, és én ezzel egyet is értek.

Másrészt a "fat model" nekem nem igazán illik a képbe, a model adatkezelésre való, nem pedig business logic implementálására (nem hiszem hogy a C-t meg az M-et jó ötlet összemosni). Persze azt is érdemes figyelembe venni, hogy a php alkalmazások (eddigi tapasztalataim szerint) erősen adatbázis-orientáltak, és a program jelentős részét tulajdonképp érdemes egyszerű CRUD műveletekként tekinteni.

Hogy a validációt hova rakja az ember, az szerintem erősen véleményes, én inkább a frontendbe tenném, mivel a hibaüzenetek előállítása (aminek része lehet a nemzetköziesítés is) a UI-ra tartozik, ezért egyszerűbb az egészet itt kezelni (mellesleg az se feltétlenül biztos, hogy egy formon csak azonos típusú entitásokat vihet be az user).

Na mindennek a jegyében én így szoktam csinálni:
* Model: saját active record ősosztály amely általános metódusokat biztosít, és a származtatott osztályokban írom meg a többi "custom" lekérdezést.

* Controller (ami szerintem a view része:)): én is igyekszem rövidre fogni, a validációt pl. külön modullal oldom meg, leginkább konfigurációs adatnak tekintem hogy melyik inputra milyen validátorokat kell futtatni, így nem lesz a controller kódja spagetti. A jogosultág-kezelést egyelőre a controllerben csinálom (azaz van-e az adott usernek joga az adott művelet elvégzéséhez), de majd később ezt is külön modulban akarom megoldani. Ha az üzleti logika triviális vagy gyakorlatilag nem létezik (egyszerű CRUD művelet) akkor a controller közvetlenül visszanyúl a modellhez - itt sérül az MVC, de így sokkal gyorsabb a fejlesztés. Ellenkező esetben az üzleti logikát külön osztályban (általában Service_* prefixszel ellátott) implementálom.

Emellett a controller gyűjti össze a template számára a paramétereket, tehát nem vagy csak minimális mértékben használok view helper-eket.