ugrás a tartalomhoz

Meghasonlás

Joó Ádám · 2011. Jan. 17. (H), 17.40

A reggeli fekete mellett ma a jól tesztelhető kód követelményein töprengtem. Nem tűnt túl laza kapcsolásnak a vezérlőben rögzíteni a modellosztály fájlnevét. Ami azt illeti, egy modellosztály nevét magát sem tűnik jó ötletnek rögzíteni, hisz bármikor felmerülhet az igény másik használatára, rögtön teszteléskor.

De ha már itt tartunk: ezen gondolatmenet mentén egyáltalán nem tűnik okosnak osztályokat nevesíteni, még a szülőét sem. Miért is ne adódhatna úgy, hogy ugyanazon osztállyal idővel egy másikat szeretnék kiterjeszteni? Így aztán persze az osztályoknak nevet adni is okafogyottá válik.

Várj.

Úgy-e, a globális változók rosszak? A hagyományos nyelvi közegben mozgónak furcsán hathat, de például Ruby-ban a szóelemzés elve azt mondja, hogy az osztály is csak objektum, a neve pedig mindprózaian egy konstans. Egy globális konstans.

Immár ebből a perspektívából is vizsgálatnak alávetve a kérdést, nem volna hát racionális az eljárásaink minden függőségét kívülről injektálni? Persze akkor még mindig ott van választott dialektusunk kész szókincse, de most képzeljünk el egy nyelvet, amiben hatókör nem öröklődik, globális elérés pedig nem létezik. Minden darab kód függőségeinek kielégítése a hívó feladata, történjék ez bár minden futáskor argumentumként, avagy előre paraméterezve curry-zés vagy ekvivalens technika használatával. Egy ilyen nyelv a biztonságra érzékeny fejlesztők Szent Grálja, Fekete köve és frígyládája lenne.

Viszont gondolkozzunk tovább! Egy olyan függvény, melynek át kell adnom azon (mondjuk beépített) osztályt, melynek példányát csak hasznosítja, de nem az művelete tárgya, vajon nem sérti-e csúnyán az információrejtés elvét, nem rútítja-e ocsmány implementációs részletekkel a felületet?

De fordítsuk meg a dolgot: ha a hívó fél eredményorientált, s a megvalósítás kérdései hidegen hagyják, úgy nem legitim-e a globális változóban tárolt adatbáziskapcsolat, mondván, hogy a modell dolga valahogy perzisztálni az adatot?

Ezen a ponton úgy érzem, lövészárokháborúba sáncoltam magam, az olvasók személyében kívánnék új harcoló feleket bevonni a konfliktus rendezése érdekében.

 
1

interfész-használat, IoC

pcjuzer · 2011. Jan. 17. (H), 17.52
interfész-használat, IoC megvan?
2

Factory Pattern, DI

erenon · 2011. Jan. 17. (H), 18.16
Amik eszembe jutottak:
Factory: bár meg kell nevezni a factoryt magát, de mégis elég azt mondanunk, hogy kérünk egy ilyet, és kapunk valamit, aminek a felülete olyan.

Dependency Injection: Ez ugye lényegében az, amit írtál. Véleményem szerint ha minden függvénynek injectálni kell az összes függőségét, az nagymértékben rondítja az interfacet.

Ha figyelembe vesszük a performance/áttekinthetőség/karbantarthatóság szempontokat, akkor ugye egy egyensúlyt kell találnunk a dinamikusság/laza közés és a tiszta interface/hardcoded függőségek között.
Szerintem általában megoldható, hogy egy rendszert kisebb modulokra szedünk szét, és ezeknek a moduloknak injectálunk külső serviceket (db, config). A kérdés az ilyen modulok mérete lehet. (Való életben ilyen modul: Django app, Symfony2 Bundle)
3

nem rútítja-e ocsmány

laco · 2011. Jan. 17. (H), 18.21
nem rútítja-e ocsmány implementációs részletekkel a felületet?

DE. :D :D :D
5

Köszi

inf · 2011. Jan. 18. (K), 01.37
Ez kellett így estére :D :D :D
4

mindig szembe fog allni

Tyrael · 2011. Jan. 17. (H), 20.44
mindig szembe fog allni egymassal ez a ket szempont.
egyik oldalrol a tokeletesen tesztelheto kod stateless, a bemeneti parameterei alapjan determinisztikus.
onnantol kezdve, hogy van akarmilyen lokalis, vagy globalis valtozod, ami allapotot tarol, mar nem igaz ez az allitas, ha tobbszor meghivod ugyanazt a fuggvenyt/metodust, ugyanarra a bemenetre tobbfele kimenetet is kaphatsz.
de ha igy tekintunk az egeszre, akkor rajovunk, hogy onnantol kezdve, hogy fajlhoz, adatbazishoz, vagy egyebb kulso eroforrashoz nyulunk (system hivas direkt(kodfuttatas) vagy indirekt modon(pl. rendszerido lekerdezese, random generalas), file muvelet, adatbazismuvelet, etc) akkor mar bevezetunk valamifele kulso dependenciat a kodba.
ezert kijelentheto, hogy nehany specialis esettol eltekintve mindig lesz valamifajta nemdetermisztikus befolyasoltsaga a kodunknak.

http://en.wikipedia.org/wiki/Functional_programming
In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state.[1] Functional programming has its roots in lambda calculus, a formal system developed in the 1930s to investigate function definition, function application, and recursion. Many functional programming languages can be viewed as elaborations on the lambda calculus.[1]
In practice, the difference between a mathematical function and the notion of a "function" used in imperative programming is that imperative functions can have side effects, changing the value of program state. Because of this they lack referential transparency, i.e. the same language expression can result in different values at different times depending on the state of the executing program. Conversely, in functional code, the output value of a function depends only on the arguments that are input to the function, so calling a function f twice with the same value for an argument x will produce the same result f(x) both times. Eliminating side effects can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming.[1]


nehany szituacioban a funkcionalis nyelvek nagyon hasznosak lehetnek, de az atlagos programozo a valos elet problemaiban tobbnyire kulonbozo allapottarto rendszerekkel kommunikal, adatokat fogad, es tovabbi, esetleg modositja is menet kozben.

A feladat megtalalni a megfelelo egyensulyt az onjaro komponensek, es a hasznalhatatlanul nehezkes, de nagyon decoupled rendszer kozott.

Tyrael
6

Mi a cél?

saxus · 2011. Jan. 18. (K), 04.12
Namost akkor gondoljuk át az egészet a józan ésszel is. Az nagyon szép, hogy adott mindenféle csudajó programozási bravúr, de lassan már olyan érzésem van, hogy ezek önálló életet élnek és valahogy elveszik miattuk a cél: adott egy feladat, amit meg kell oldani.

Nem fogok dependency injectiont használni mindenhol mert az a divatos. Majd ott, ahol szükséges. Halál nyugodtan be fogom vezetni azt a 3-4-5 db. globális változót, amiről tudom, hogy az márpedig fix, és azt fogja használni minden, ha tetszik ha nem, mert az esetek 99%-ában ez fog kelleni. (Maradék 1% miatt meg nem fogom szívatni magam).

Azt látom mostanság, hogy egy primitív blogmotort nem tudnak ma már megírni az emberek MVC pattern, valamilyen keretrendszer és hozzá külön egy entity framework nélkül. Nem látom értelmét az architektúrális felhőkarcolók építgetésének csak azért, hogy legyenek meg mert ez a divat mostanság. Vagy hozhatnám példának az MVVM patternt. Nagyon szép és jó, hogy agyonrétegezett, de 6*10^23 rétegen kell átvezetnem mindent, és horribilis mennyiségű kódot kell írnom csak azért, hogy szép legyen.

Igazából aki a mindenféle modern és divatos eszköz használatát fontolgatja, annak csak azt tudom javasolni, hogy először is gondolja át, hogy valóban kell-e ez neki és valóban ad-e annyi pluszt, mint amennyit elvesz (idő, mire megtanulja, idő, mire a meglévő kódokat átportolja/újraírja az új módszerhez, időtöbblet a régi és az új módszerhez képest).
7

Szépen kialakult a thread

deejayy · 2011. Jan. 18. (K), 12.26
Szépen kialakult a thread affelé, amire én is gondoltam mostanság. MVC keretrendszert használok, és mindig ott a dilemma, az _összes_ kódsornál, hogy akkor ezt most M-be, V-be vagy C-be tegyem, attól függően, mit csinál.

Szörnyű, és a döntések többségében megérzésből választok, ami azt eredményezi, hogy ugyanaz a kódsor (kicsit módosítva persze) egyszer a controlban, egyszer meg a view-ban van. Valahogy sosem sikerül eltalálnom, hogy hova _szoktam_, és logikusan végiggondolva pedig mindkét helyre beillene.

Ezért többször van az, hogy átnézek fölöslegesen két réteget csak azért, hogy tudjam, mit hova tettem, illetve, éppen hova kellene tennem azt, ami a fejemben van.

(Azt most meg sem említem, hogy nem csak az adatbázis tábláknak, de a hasonló nevű view-knak is vannak nálam MVC megfelelői, és pl. a renderelést azokhoz teszem, mert abban vannak a megfelelő adatok. A módosítást meg a base táblába, mert dbview-n keresztül ne módosítsunk már adatot. Így meg aztán szorzódnak a lehetséges helyek :)
8

MVC keretrendszert használok,

inf · 2011. Jan. 18. (K), 13.14
MVC keretrendszert használok, és mindig ott a dilemma, az _összes_ kódsornál, hogy akkor ezt most M-be, V-be vagy C-be tegyem, attól függően, mit csinál.


Tudnál példát mondani? Én nehezen tudom elképzelni, hogy azon dilemmázok, hogy mi hova menjen, de kíváncsi vagyok, hátha tényleg van ilyen helyzet. :-)
15

Például. Amikor egy

deejayy · 2011. Jan. 19. (Sze), 09.10
Például.

Amikor egy táblázatot iratok ki úgy, hogy mondjuk adott tartalmú sorait kiszűröm (whateva, hogy miért php oldalon szűrök, csak a példa kedvéért).

Mert ugye a mondás az, hogy a renderelés a view-ban történjen, tehát szépen átadom a modelből visszakapott adatokat a template rendszernek, és az meg kiírja. Viszont a sorokon végig kell mennem, hogy tudjam, hogy irassam-e ki vagy sem.

A kérdés:
- controlban iterálok, és külön metódusokat hívok meg a view-ban a táblázat keretének és sorainak kiiratására
- az egész iterációt feltételvizsgálattal beleteszem a view-ba
- controlból hívok meg egy view metódust, ami visszaad egy html kódot, majd azt továbbadom egy másik view metódusnak

Egyéb szcenárió? :)
17

Más

Poetro · 2011. Jan. 19. (Sze), 12.24
A control-ban iterálsz, és miután végeztél, adod át a view rétegnek az egészet egyben.
19

Mi az egész? :) Na, legyen

deejayy · 2011. Jan. 25. (K), 15.35
Mi az egész? :)

Na, legyen világos a példa: 5 usert kell kilistáznom táblázatban úgy, hogy a 3-as id-jűt nem írom ki. Tekintsünk el attól, hogy ez sql-ben könnyen megoldható, a kérdés nem erre vonatkozik.

Tehát mi hol foglal helyet ebben az esetben?

inf3rno egyébként azt mondja, hogy a szűrést a view-ban oldjam meg.

A "nagyjából mindegy" pedig szüli az inkonzisztenciákat, tehát valamihez kötni kell, különben hol itt lesz, hol ott.
20

Feldolgozás

Poetro · 2011. Jan. 25. (K), 16.06
Ahogy én csinálnám:

Controller:
Feldolgoznám a kérést, ami ugye megmondja, hogy mit kell listázni, és ebből mit nem kell megjeleníteni.

Model:
Elvégzi a lekérdezést, majd kiszűri az adatokat, vagy amennyiben lehetséges, akkor már maga kiszűri a nem szükséges adatokat.

View:
Megjeleníti a táblázatot, amiben minden átadott adat benne van. Már nem kell a szűréssel foglalkozni, mivel az adat már fel van dolgozva. Amennyiben meg kell jeleníteni 3-as IDjű elemet, de mondjuk más színnel ki kell emelni, akkor pedig a szűrést már a View rétegbe tenném.
21

A Controller semmi mast nem

Tyrael · 2011. Jan. 25. (K), 18.23
A Controller semmi mast nem csinal, mint a beeso kerest mappeli a business logichoz, valamint az innen kapott eredmenyt bemenetkent atadja a View-nak, majd kitolja a kimenetet a usernek.
Amibol szerintem a legtobb kavarodas van, az az, hogy sok ember nincs tisztaban vele, hogy nem csak egyfele model van, legalabbis az MVC-ben helyett foglalo M betu nem csak egyfele modelt takar, viszont sokan hajlamosak abba a hitbe esni, hogy ez a Model csak a DAO modelleket jelenti, pedig ugye a modelleknek ez csak egy nagyon kis resze, gyakorlatilag a teljes alkalmazaslogikanak itt van a helye (Tehat van egy Modellunk, ami a felhasznalokat listazasahoz kikeresi a felhasznalokat, ennek a Controller atadhatja, esetleg transzformalhatja a bemeneti parametereit, majd ezt a model-t, vagy ennek az eredmenyet atadja a View-nak, ahol a latogato szamara reprezentativ formaban megjelenitesre kerul).
http://en.wikipedia.org/wiki/Model-view-controller
http://en.wikipedia.org/wiki/Multitier_architecture
http://en.wikipedia.org/wiki/Business_layer

Tyrael
22

+1

inf · 2011. Jan. 27. (Cs), 17.57
Yepp.

Kavarodás nem csak a modelnél van, hanem a viewnál is, sokan keverik a view réteget a sablon rendszerrel ugyanúgy, mint a modelt a dao-val.
23

Kérdés

Max Logan · 2011. Jan. 27. (Cs), 18.21
Nálam már korábban letisztult az, hogy a réteg fogalma nem egyenlő egy-egy megoldással. Már csak az nem egyértelmű, hogy model réteg alatt egy-egy ősosztolyt értünk a controller szemszögéből, amit aztán úgy gyújunk át az öröklés révén, ahogyan akarunk, vagy tetszőleges formátumú és megoldásokkal rendelkező osztálycsoportként tekintünk a modell-re? Meg az is érdekes, ami fentebb szóba került, hogy csak pusztán adatokat adjunk át a view-nak (változók), vagy az egész modell objektumot, objektumokat? És ugyanez a minek nevezzük kérdsés van a fejemben a view esetén is.
24

Ha kicsit jobban megnézed a

inf · 2011. Jan. 27. (Cs), 20.10
Ha kicsit jobban megnézed a képet jobb oldalt, akkor azt hiszem választ kapsz a kérdésedre.
25

Model alatt nem 1-1

Tyrael · 2011. Jan. 28. (P), 11.52
Model alatt nem 1-1 ososztalyt ertunk, hiszen mint mondtam, tobbfele model van, ezert nem feltetlenul van olyan kozos funkciojuk, ami alapjan lehetne prototipust/baseclasst definialni hozza, tehat a masodik megkozelitesed a helyes.
masodik kerdesedet itt nagyon szepen megvitattak

Tyrael
18

A kérdés: - controlban

inf · 2011. Jan. 19. (Sze), 12.44
A kérdés:
- controlban iterálok, és külön metódusokat hívok meg a view-ban a táblázat keretének és sorainak kiiratására
- az egész iterációt feltételvizsgálattal beleteszem a view-ba
- controlból hívok meg egy view metódust, ami visszaad egy html kódot, majd azt továbbadom egy másik view metódusnak

Egyéb szcenárió? :)


A controller-nek inkább olyan feladata van szerintem, hogy az auth-ot lekezelje, ellenőrizze a jogosultságokat, a post adatokat validálja, és eljuttassa őket a megfelelő model/view példányokhoz. Ha már megtörtént aminek kellett, mondjuk egy tábla módosítása, stb, akkor a kirajzolásnál a view fog irányítani. Szóval a te esetedben a view fogja elkérni az adatokat a model-től a táblázathoz. Az adatok szűrését megoldhatod a model-ben és a view-ban is, nagyjából mindegy, nyilván ha az sql-be be tudod tenni, akkor a model-be fog kerülni a dolog.

(A template nem egyenlő a view-al. A view használhat templateket arra, hogy szöveges formára hozza az adatokat, ha éppen arra van szükség, de mondjuk egy képet sosem fogsz kirajzolni templattel.)
9

http://www.youtube.com/result

Tyrael · 2011. Jan. 18. (K), 14.31
nezd vegig a 6 "MVC Public Service Announcement" videot

Tyrael
10

MVC esetében például egészen

gphilip · 2011. Jan. 18. (K), 18.42
MVC esetében például egészen jól definiált, hogy mit hova kell tenned, ha ezen töröd a fejed, akkor talán nem ismered annyira :) (no offense)

Saxus: "horribilis mennyiségű kódot kell írnom csak azért, hogy szép legyen." pedig pont az ellenkezője a lényeg, a szerepkörök jó elkülönítése, a kód újrafelhasználhatósága.

Persze nem vitatom, hogy sok technika "hasznossága" függ a projekt méretétől is, de egy e-mail form vagy egy szavazás box esetében nincs is értelme ezeknek a fogalmaknak, értelemszerűen nagy méretű projektekre vonatkoznak.
11

"értelemszerűen nagy méretű projektekre"

saxus · 2011. Jan. 18. (K), 20.11
Igen, pontosan. És pont ez a probléma, elveszett a lényege az egésznek.

Az általam fentebb említett MVVM patternnek is látom az értelmét, csak épp nem ott, ahol a projektek 90%-a készül, főleg itthon. Ellenben viszont a trend az, hogy ész nélkül használjuk mindenre az MVC, ORM mapping és hasonló három betűs megoldásokat, holott ugyanolyan szépen meg lehetne oldani, csak épp nem "trendi" ezért "nem szép".

Pl. egyszer úgy nézett ki, hogy átadunk egy projekt részfeladatát egy külsős programozónak. Mikor szóba került, hogy mi a véleménye a projektről, csak annyit tudott hozzátenni, hogy "nagy szar" a miértre meg azt, hogy "mert globális változók vannak benne". Na most a projektben legalább 3 részt tudnék mondani, ami az idők folyamán nagyon csúnyán elgányolódott az örökös variálás és toldozás-foltozás mellett, és az a 4 globális változó zavarja a legkevesebb vizet...
12

Alapvetően egyetértek veled

gphilip · 2011. Jan. 18. (K), 20.19
Alapvetően egyetértek veled :)

Annyiban tér el a véleményünk, hogy itt nem a szépségről van szó, annál sokkal fontosabb dolgokról... Ha az 5 osztályt használó személyes blogodban ki kell cserélned a template engine-t vagy az adatbázismotort, akkor esetleg egy search-and-replace-szel meg egy fél órás hegesztéssel meg is vagy.

Ha ezt egy megfelelő absztrakciót nélkülöző több százezer kódsorból felépülő rendszerben kell megtenned, ott már szaban vagy :) nem a szépség a lényeg, hanem a maintainability, reusability, ease of testing, és hasonló magyarul hülyén hangzó kifejezések :)
13

Magyarul hülyén hangzó

Joó Ádám · 2011. Jan. 18. (K), 21.10
Karbantarthatóság, újrafelhasználhatóság és könnyű tesztelhetőség? :)
14

Rendben, helyesbítek,

gphilip · 2011. Jan. 18. (K), 23.16
Rendben, helyesbítek, _számomra_ hülyén hangzó :)

de ez egy végtelen hosszú beszélgetés tárgya lehetne, valószínűleg mindenkinek az hangzik "nemhülyén", ahogy eredetileg ismer egy szakkifejezést... valószínűleg az "egyke osztály" sem mindenkinek borzolja fel a hátán a szőrt. :)
16

Alapveto epitokovek csereje

saxus · 2011. Jan. 19. (Sze), 11.37
Azon kivul, hogy a sajat rendszeremben barmikor le tudnam cserelni az SQL reteget (leszamitva nehany dbspecifikus queryt hasznalo modult) vagy a template rendszert, figyelembe veve, hogy van egy interface, amit hasznaltak, igazabol azt nem ertem, hogy miert akarnam lecserelni a rendszerem legalapvetobb epitokoveit...

Masik: sajnos a tapasztalatom az, hogy szep szo a kodujrafelhasznalhatosag (megis mi a baj vele?), de a keretrendszer relative fix, a modulokban meg ugy is van olyan kulonbseg, hogy idovel elganyolodjanak, ha valoban hozza kell nyulni. Ilyenkor neha tisztabb-szarazabb uj dolgot tervezni a regi kodreszleteket felhasznalva.