ugrás a tartalomhoz

Objektum v. elemi adat?

eddig bírtam szó nélkül · 2012. Szep. 9. (V), 19.49
Azon töröm a fejem, hogy ha van egy osztályom, amelyet adatstruktúraként használok, akkor a benne lévő, logikailag elemi adatokat miképp kezeljem?
(Tiszta kódot olvastam már megint, de nem találom azt a részt, ahol szóba került, hogy egy objektum lehet adattároló is, spec. metódusok nélkül, de akkor csak adatokat publikáljon, vagy lehet olyan, ami pl. üzleti logikát valósít meg, de annak ne legyen publikus változója, csak metódusai)

Valóban legyenek elemi adatok és maga az osztály feleljen azért, hogy csak validált értékek kerülhessenek az egyes változókba?
Vagy az egyes, elemi adatokat tartalmazó változók maguk is objektumok legyenek, amelyek önmagukat képesek ellenőrizni?
Van erre is valamiféle "előírás" az objektum orientált programozással kapcsolatban?

Programnyelvet szándékosan nem említettem, de pl. java-ban, PHP-ben ennek inkább lehet jelentősége, mint egy olyan nyelvben, mint a python v. a ruby, ahol minden objektum, így kevésbé okoz lelki problémát a döntés.
 
1

Fogaskerekek

Pepita · 2012. Szep. 9. (V), 20.22
Jól megtekergeted a tekervényeimet megint! :)
egy objektum lehet adattároló is, spec. metódusok nélkül, de akkor csak adatokat publikáljon, vagy lehet olyan, ami pl. üzleti logikát valósít meg, de annak ne legyen publikus változója, csak metódusai
Ez így nem igaz, a kettő egyáltalán nem zárja ki egymást.
Pl. gondolj az <img> (html) tag-re, mint egy objektumra. (Itt nem a html a legjobb példa, mert ott a böngésző is, de gondold azt, hogy "programnyelv". Delphiben pl. ilyen a TImage komonens - egy osztály.) Nem pusztán adattároló, mert (közvetve) meg is jeleníti a képet, sőt, "kezelni tud" eltérő típusú fájlokat is. Viszont adott esetben néhány mega adatot is tárol közben. Sőt, letölti a kép bájtjait a szerverről, kicsomagolja a tömörített képet, stb.

De ami a lényeg: egy jól körülhatárolt feladatot végez el, mégha ez egy komplexebb feladat is. Ezt úgy tudja megoldani, hogy egyszerre adattároló is és funkcionális is. Ez a legtöbb feladat esetében így van, ezért még nem kell több osztályban megvalósítani.

Vagy az egyes, elemi adatokat tartalmazó változók maguk is objektumok legyenek, amelyek önmagukat képesek ellenőrizni?
Erre nincs tuti szabály, a változó bonyolultságától és a te szemléletedtől függ. Ha mindent a legapróbb részletekig szét akarsz (vagy a könyved) bontani külön-külön osztályokra, akkor tedd azt. (Ez esetben Inferno több tanáccsal szolgálhat, mint én.) De ezt sem jó túlzásba vinni, mert lassabban írod meg, és nehezebben is hasznosítod a későbbiekben. Nekem egy-egy osztályom forráskódja a sok üres sorral együtt be szokott férni 400 sorba, de nem mondom azt, hogy el van k...va, ha 800-ra sikerül.
De azt hiszem ez a "kinek hosszabbak az osztályai" már volt téma. Nem (csak) ezen múlik az OOP.

Változókat ellenőrizni is sokféle módon és helyen lehet, nincs egyetemes "legjobb megoldás", mindig a feladat / programozó függvénye.
2

Valami félreértés van a

eddig bírtam szó nélkül · 2012. Szep. 9. (V), 20.48
Valami félreértés van a dologban:
egy osztály lehet adattároló (kb. a C struct-nak v. a COBOL Data Division-ben leírt rekordoknak megfelelőnek képzelem), ilyenkor publikus adattagjai vannak.
PHP-re fordítva az adattároló objektum változóira közvetlenül hivatkozhatsz: $objektum->valtozo.
Ebben az esetben (ha jól értem), az osztály/objektum szerepe kimerül az adatok tárolásában, max. getter/setter metódusai lehetnek.

Illetve lehet hagyományos értelemben vett objektum, de akkor az OOP alapelvek szerint az adattagokat nem publikálhatod (lásd egységbezárás vagymi... ;-) ), kizárólag publikus metódusok segítségével kommunikálhat a "külvilággal".

És akkor ezek keveréke az ActiveRecord, ami aztán végképp bekavart, az említésekor végképp elvesztettem a fonalat. :-)
----

Ami az ellenőrzést illeti, itt most kifejezetten arról beszélek, hogy van egy osztályom/objektumom, amiben adatokat tárolnék, de azt akarom, hogy ezek mind ellenőrzött adatok legyenek. Nem teljes körű, logikai ellenőrzésre gondolok, hanem szintaktikai ellenőrzésre, önmagában értelmezhető értéktartományra stb.)

Bizonyos szempontból azt tartanám jobbnak, ha a elemi adatokat tárolnék és az osztály en bloc ellenőrizné valamennyi bemenő adatát. (mondjuk azért, mert ezek egy adatbázis tábla mezőinek leképezései)

Viszont ha a SRP-t próbálom szem előtt tartani, pontosabban azt, hogy egy osztálynak csak egyetlen oka lehet a változásra, akkor valamennyi benne tárolt "elemi" adatnak önálló objektumnak kell lennie, amely implementálja az ellenőrzéshez szükséges interface-t.
(és ezt meddig lehetne még bonyolítani... :-)) )
6

PHP OOP...

Pepita · 2012. Szep. 10. (H), 23.37
Na, ha PHP-re "fordítunk", akkor a $objektum->valtozo = valami máris egy sor hibalehetőséget hordoz, a gyengén típusosság miatt. Így, publikus adattaggal, nem tudod ellenőrizni az adat helyességét. A "getter/setter" metódusok ezt hivatottak megvalósítani. Namost az, hogy az objektumomnak van pár ilyen metódusa, nem jelenti azt, hogy egyéb (pl. "üzleti") logikát nem valósíthat meg. De ilyen logika lehet az is, amikor az adatok összeférhetőségét vizsgálod. Ez pl. egy külön privát függvény, amit minden setter végén / közben meghívsz.

Szerintem a feladat / szemlélet dönti el, hogy az adott esetben mikor és mennyire van értelme többfelé bontani az osztályt.
3

Valóban legyenek elemi adatok

Joó Ádám · 2012. Szep. 9. (V), 21.01
Valóban legyenek elemi adatok és maga az osztály feleljen azért, hogy csak validált értékek kerülhessenek az egyes változókba? Vagy az egyes, elemi adatokat tartalmazó változók maguk is objektumok legyenek, amelyek önmagukat képesek ellenőrizni?


Minden változó maga felel az általa tárolt adatokért, típusától függően. Egy összetett adatszerkezet, mint egy osztály, az alkotóelemei közötti konzisztenciáért felel. Vannak programnyelvek, amik ebben segítenek, és vannak, amik nem. A PHP vagy a Java nem.
4

Köszi! Szóval bármennyire

eddig bírtam szó nélkül · 2012. Szep. 9. (V), 21.30
Köszi! Szóval bármennyire "nemszeretem" az ötlet, ha egy "integer"-hez szeretnék tól-ig limitet beállítani, akkor objektum kell az integer helyére, ami ellenőrzi, hogy megfelelő intervallumba tartozó értéket kapott-e, az őt magába fogadó osztálynak pedig max. az ellenőrző metódus meghívása a feladata (vagy még az sem, mert a setternek kutya kötelessége az ellenőrzés)...

Tudnál példát mondani olyan nyelvre, ami segít az adattagok közti konzisztencia ellenőrzésében?
5

Az érték átadásakor az

Joó Ádám · 2012. Szep. 10. (H), 17.04
Az érték átadásakor az értékkapó objektum felelőssége ellenőrizni, hogy az érték megfelel-e az objektum típusának. Az őt magába foglaló adatszerkezet felelőssége ellenőrizni, hogy az önmagában az adattag típusának megfelelő érték a többi adattaggal együtt megfelel-e az összetett típusnak. A http.request osztály method adattagjának adhatsz értékül GET-et, de kivételt kapsz a @GET-re. De hiába adsz neki értékül GET-et, ha a body adattagja nem üres, mert akkor a request osztály maga fog kivételt dobni.

Ahhoz, hogy ez automatikusan megvalósuljon, az értékadás esemény szülőirányú tovaterjedésére volna szükség. Nem ismerek olyan programnyelvet, ami ezt megvalósítaná.

Ennek hiányában a megvalósításnak két útja lehetséges. A szkriptnyelvek általában lehetővé teszik, hogy az osztály elkapja az adattagra vonatkozó értékadást. Ilyenkor az osztályban meghívhatod az adattag – szándékozott – típusához tartozó ellenőrzőfüggvényt, majd ha azon átjut az érték, ellenőrizheted, hogy az osztály többi adattagjával összefér-e.

És vannak olyan nyelvek, amikben az adattag maga végzi az ellenőrzést, amikor értéket kap, azonban az osztály nem veszi észre, hogy egy eleme változott, így ebben az esetben az adatok közti konzisztencia ellenőrzéséhez kell külön függvényt hívnod. Esetleg az adattag tárolhat az őt magába foglaló objektumra hivatkozást, és az értékadáskor kezdeményezheti az ellenőrzést.
11

Biztosan velem van a baj, de

eddig bírtam szó nélkül · 2012. Szep. 11. (K), 15.41
Biztosan velem van a baj, de az első bekezdésből egy szót sem értek... Milyen GET és @GET? És az utóbbi miért dob exceptiont? Egyáltalán: kinek a micsodája a http.request osztály? (bocs, momentán egyedül pythonnal vagyok valamelyest képben, azzal is inkább desktopon, PHP-s keretrendszereket meg egyáltalán nem ismerek)

A másik: a korábbi hozzászólásodban te írtad, hogy
Vannak programnyelvek, amik ebben segítenek, és vannak, amik nem.

Ezért kérdeztem, hogy tudnál-e konkrét példát azokra, amelyek segítenek...
13

Biztosan velem van a baj, de

Joó Ádám · 2012. Szep. 11. (K), 16.51
Biztosan velem van a baj, de az első bekezdésből egy szót sem értek... Milyen GET és @GET? És az utóbbi miért dob exceptiont? Egyáltalán: kinek a micsodája a http.request osztály? (bocs, momentán egyedül pythonnal vagyok valamelyest képben, azzal is inkább desktopon, PHP-s keretrendszereket meg egyáltalán nem ismerek)


Egy hipotetikus programnyelv hipotetikus HTTP könyvtárát hoztam példának. Feltételezem, hogy ismered a HTTP protokoll működését, így tudod, mi az a GET. A @GET egy szintaktikailag hibás metódusra volt példa.

Minden változó maga felel az általa tárolt adatokért, típusától függően.


Ehhez a fő gondolathoz tartozott a megjegyzés, miszerint vannak programnyelvek, amik segítenek benne. Bármelyik programnyelv lehet rá példa, amelyik erősen típusos és/vagy lehetővé teszi az értékadás művelet felülírását. A C++ ilyen, a PHP nem.

Az adatok közti konzisztencia ellenőrzésére bármelyik programnyelv jó példa, amelyik lehetővé teszi invariáns definiálását az adatszerkezethez és/vagy az osztály értesítést kap egy adattagja változásáról. A PHP tudja az utóbbit, az Eiffel és a D talán az előbbit, a C++ egyiket sem.
14

OK, akkor totálisan

eddig bírtam szó nélkül · 2012. Szep. 11. (K), 20.16
OK, akkor totálisan félreértettem a példádat. (hogy ismerem a http-t az enyhe túlzás, de volt már rá példa, hogy telnet segítségével társalogtam web szerverrel :-) )

Programnyelvek: java7-ben sem lehet felülírni az értékadást? Úgy emlékszem, anno a tervek közt szerepelt valami ilyesmi is... Illetve a másik (még nem néztem utána): a C++ engedi felülírni egy int típusú változó értékadását is?
15

a C++ engedi felülírni egy

Joó Ádám · 2012. Szep. 11. (K), 23.53
a C++ engedi felülírni egy int típusú változó értékadását is?


Nem, de írhatsz egy saját egész osztályt. Más nyelvekben pedig rendelhetsz megengedett intervallumot a skalár típusodhoz.
7

Attól függ

Pepita · 2012. Szep. 11. (K), 00.00
Szóval bármennyire "nemszeretem" az ötlet, ha egy "integer"-hez szeretnék tól-ig limitet beállítani, akkor objektum kell az integer helyére...
Feltételezem, hogy az "integer" egy osztály (legyen "Osztaly") (belső) változója. Akkor kell külön "Limited_int" osztályt deklarálnod, ha ezt a típust nem csak az "Osztaly"-ban akarod használni, hanem pl. "Masik_osztaly"-ban is, ami viszont nem az "Osztaly" leszármazottja. Ha viszont a "Limited_int"-et kizárólag az "Osztaly"-ban használod, akkor felesleges külön osztályban deklarálni, egyszerűen privát a változó, és írsz hozzá publikus read / write függvényeket, utóbbit ellenőrzéssel.
Mivel a legtöbb esetben nem tudni, hogy "100 év múlva" nem lesz-e szükség mégis valahol a "Limited_int"-re, ezért javasolják sokan, hogy mindenképp külön osztályban valósítsd meg.

Tudnál példát mondani olyan nyelvre, ami segít az adattagok közti konzisztencia ellenőrzésében?
Ha jól értem a kérdést, akkor a Delphi (ObjectPascal) ilyen. Itt fordításkor kiderülnek a típuskompatibilitási problémák, és minden (felhasználó által) szerkeszthető tulajdonsággal bíró komponensnek van onChange metódusa, amiben azt csinálsz, amihez kedved van. Továbbá (ha Windowsra programozol) egy sor onKeypress, onKeydown, onMousedown, onClick, stb. De az adatok limitálását, stb. neked kell kódolnod, de ezt megteheted úgy is, hogy egy meglévő komponensből újat származtatsz és meg-/felülírod a neked megfelelő metódusát.
8

A Clean Code-ban az a rész

inf3rno · 2012. Szep. 11. (K), 02.20
A Clean Code-ban az a rész arról szól, hogy vannak adatstruktúrák és vannak objektumok, és külön-külön mindkét megoldás jó lehet bizonyos célok elérésére, de a kettő keveréke használhatatlan.
Az adatstruktúrák olyanok, hogy az ő feladatok az adattárolás, és ha módosítani akarod a bennük lévő adatokat, akkor át kell adnod őket olyan függvényeknek, amiknek pont ez a módosítás a feladatuk. Szóval az ő adataiknak a manipulálása kívülről megy. Az objektumoknál az objektum elrejti, hogy milyen adat van benne, az adatok manipulálása pedig belülről; az objektum metódusaival megy.

A könyvben erről van egy csomó példa, többek között olyan is, ami koordinátákkal szemléltet.

vektor adatstruktúrák:

class DescartesVector {
	public $x;
	public $y;
}

class PolarVector {
	public $radius;
	public $angle;
}

class VectorTransformer {
	public function toPolar(DescartesVector $descartesVector); //return PolarVector
	public function toDescartes(); //return DescartesVector
}
Az adatstruktúráknál az új típus bevezetése a nehéz, mert az őket manipuláló osztály jelentősen meg fog változni. Új metódus felvétele viszont könnyű, mert csak a manipuláló osztályon kell létrehozni egyet.

vektor objektum:

class Vector {

	public function setX($x);
	public function getX();

	public function setY($y);
	public function getY();

	public function setRadius($r);
	public function getRadius();

	public function setAngle($a);
	public function getAngle();
}
Objekutmoknál az új típus felvétele könnyű, mert létrehozol neki egy új osztályt, és kész. Az új metódus felvétele viszont nehéz, mert minden egyes típusnak az osztályán létre kell hozni egy-egy metódust.

Ez a koordinátás példa ezt egy kicsit máshogy mutatja. Tegyük fel, hogy van még egy vektorokat leíró módszer, mondjuk ami komplex számot ad vissza, vagy bármi más (lényegtelen igazából, hogy micsoda). Ha ezt az új típust hozzá akarjuk adni az adatstruktúrás megoldáshoz, akkor létre kell hozni a transformeren egy oda és egy vissza alakító metódust mindkét meglévő típushoz, tehát összesen 4 új metódusra és egy új struktúrára lesz szükség. Ezzel szemben, ha az objektumos módszert követjük, akkor elég 2 új metódus: a tárolási adat formára konvertálás és az onnan vissza konvertálás.


Ha objektumokkal dolgozol, és nem adatstruktúrákkal, akkor ha előjön olyan helyzet, hogy egy objektum egy másik objektum adatait lekéri, manipulálja, majd újra beállítja rajta, akkor az elvi hiba, mert az objektum nem adja ki az adatait manipulálásra, hanem ő maga manipulálja őket. Az adatstruktúráknál persze pont, hogy ez a járható út... Az, hogy neked éppen melyikre van szükséged a te döntésed.

A típusellenőrzést tartalmazhatják az adatstruktúrák, ha setterrel és getterrel oldod meg bennük az értékadást. Az, hogy mondjuk egy szám egy adott tartományba esik e, szerintem nem számít szigorúan típusellenőrzésnek. Ha sokszor ismétlődik ez a fajta ellenőrzés, akkor ki lehet emelni külön osztályba, mint új típust, ha viszont nem gyakori az ilyesmi, akkor nem tartom fontosnak. Szóval ez eléggé helyzet meg mentalitás függő. Én viszonylag toleráns vagyok ilyen téren, nem szoktam rövid kódokat 1-2 ismétlődés miatt kiemelni, mert nem akarok túl általános kódot írni. Clean Code-ban azt írják, hogy már egy ismétlődés elég ok arra, hogy kiemeljed új metódusba vagy új osztályba az adott kódot.
9

Ha inged...

Pepita · 2012. Szep. 11. (K), 06.58
Ha inged, vedd magadra, én viszont feladat-orientált vagyok, nem alkalmazok ilyen szabályokat "pepitában". Ha úgy jobb, így csinálom, de nem feltétlenül.
10

Azért jobb úgy, mert minél

inf3rno · 2012. Szep. 11. (K), 14.09
Azért jobb úgy, mert minél több az ismétlődő kód annál valószínűbb, hogy valamelyik másolata hibás lesz. Olyan ez, mint a DNS-nél a pontmutáció, bizonyos számú másolat után spontán kialakul...
17

HA van ismétlődő kód

Pepita · 2012. Szep. 12. (Sze), 01.13
Pont ez az, amiért vitatom, hogy feketén-fehéren igaz lenne ez az elmélet. Sokszor csinálunk úgy egy osztályt, hogy egyetlen projektben használjuk fel, ezt szétbontani 5-6 osztályra azért, hogy "szép legyen", és mindenből csak 1-1 példány van, hát...
Ezen kívül van egy olyan hátránya is a - mondjuk így - túlzásba vitt öröklődésnek / származtatásnak, hogy ha vmelyik "alap" osztályodat kell módosítani, akkor adott esetben mehetsz végig az összes gyermekén is, ahol felhasználtad. Persze ez akkor fordul elő, ha az elején b...ál el vmit.

Csak azt vitatom, hogy ez mindig és mindenhol igaz; tisztában vagyok vele, hogy sokszor igaz.

Kíváncsian várom a cikksorozatot, de nem ígérem, hogy nem fogok ott is vitatkozni... :)

Szerk.: ehhez a DNS mittoménmihez nagyon nem tudok hozzászagolni, ez ehető vagy iható? :)
18

A rossz tervezés nem az

MadBence · 2012. Szep. 12. (Sze), 02.01
A rossz tervezés nem az elmélet hibája, hanem a programozóé (vagy aki tervezte a rendszert). Azon nem segít semmi, csak az újratervezés (ezzel együtt a kód újraírása) :).
Ha meg módosítani kell valamit, és nem hozzáadni, az meg tervezési hiba.
De amúgy igazad van, nem kell mindig teljesen következetesen az időt ilyen "szépítésre" szánni, határidő közeledtével az ember örül, ha egyáltalán működik/lefordul a cucc. (Ezt hívják Fear Driven Developement-nek :) )
19

Biztos?

Pepita · 2012. Szep. 12. (Sze), 02.20
Ha meg módosítani kell valamit, és nem hozzáadni, az meg tervezési hiba.
Meggondolta magát a Megrendelő, módosítást kér, másképp nem akar fizetni, ... - ez mind tervezési hiba? Ezek ellen te hogy védekezel tervezési időben? Mert én ilyen okokból szoktam módosítani.
22

Ezen kívül van egy olyan

inf3rno · 2012. Szep. 12. (Sze), 02.38
Ezen kívül van egy olyan hátránya is a - mondjuk így - túlzásba vitt öröklődésnek / származtatásnak, hogy ha vmelyik "alap" osztályodat kell módosítani, akkor adott esetben mehetsz végig az összes gyermekén is, ahol felhasználtad.


Nem hiszem, hogyha ezeket az elveket betartod, akkor muszáj lenne túlzásba vinni az örököltetést. Ez inkább arról szól, hogy sok pici segédosztályod van, de ha küldesz példakódot, ahol szerinted csak így lehet megoldani, akkor szívesen megpróbálom bizonyítani az ellenkezőjét. :-)
23

Mihez képest

Pepita · 2012. Szep. 12. (Sze), 03.01
Nem hiszem, hogyha ezeket az elveket betartod, akkor muszáj lenne túlzásba vinni az örököltetést.
Nem muszáj. És a túlzás is kinek mennyi. Te "szereted" a sok pici segédosztályodat, én nem annyira -> hozzám képest Te túlzol. Felőled nézve viszont én nem vagyok elég alapos. A lényeg az, hogy ettől egyikünk sem rosszabb programozó.

Mivel ez elvi-szemléleti kérdés (és én nem is állítottam semmi olyat, hogy "csak így lehet"), nem tartom hasznosnak a kód-ping-pongot, és lehet, hogy a további vitát sem. Bár a vita olyanformán hasznos, hogy kódolás közben is eszembe jut néha, így segít több-jobb szemszögből nézni u.azt a dolgot, de szerintem soha nem leszek annyira "darabolós gyilkos" (:)), mint te. Egyébként lehet, hogy nincs is olyan sok különbség a nézetünk közt, csak pár árnyalatnyi (nüansznyi?).
24

Ki tudja :D

inf3rno · 2012. Szep. 12. (Sze), 03.42
Ki tudja :D
20

Valahol én is egyetértek.

inf3rno · 2012. Szep. 12. (Sze), 02.23
Valahol én is egyetértek. Ezek a szabályok jók, de érdemes belevinni egy kis rugalmasságot a dologba, hogy ne akadjunk fenn nüanszokon. (szerintem még ezt a szót sem használtam soha, apróságokat akartam mondani, csak nem jutott eszembe :D)
21

Ki mennyire

Pepita · 2012. Szep. 12. (Sze), 02.30
Igen, az "egy kis" rugalmasság a jó kifejezés. Aztán ez kinek mennyi. Én a Delphi-s megoldásokból "örököltem" szemléletem nagyrészét. És nekem eddig bejött.
12

A könyvben, ahol beleakadtam

eddig bírtam szó nélkül · 2012. Szep. 11. (K), 15.49
A könyvben, ahol beleakadtam ebbe a témába, csak mellékszálként emlegette a szerző, kb. egy mondattal elintézve.

A többire próbálok majd értelmesen reagálni, de egyelőre nehezemre esik felfogni amit írtál...
16

Egyébként így, hogy végre

inf3rno · 2012. Szep. 12. (Sze), 00.42
Egyébként így, hogy végre valahára a végére értem a clean code-nak, már nem tartom 10/10-nek. Az elvek nagyrésze jó, amiket előad, de van benne egy pár olyan rész, ami könnyen félreérthető, tehát rosszul van elmagyarázva. Ilyen pl ez az objektum vs adatstruktúra rész is. Ezen kívül pl van egy olyan rész, ahol azt sorolja fel, hogy and meg if meg ilyen szavak nem lehetnek metódus nevekben, márpedig lehetnek, csak azoknak a metódusoknak a blokkját szépen fel kell darabolni kisebb metódusokra az elnevezés szerint. A vége felé pont a szerző hoz fel erre példákat tök másból kifolyólag... Nálam lecsúszott 8/10-re ezek miatt.

Még elolvasok pár könyvet, aztán írok ide clean code-os cikk sorozatot, meg tervben van egy oldal, ahova fel tudom tenni a példáimat. A gondom, hogy refactoring nyomonkövetésére még nem láttam semmi használható megjelenítési módot. Egyedül ilyen van, hogy kivastagozzák a lépéseket, de az leírva elég gáz, mert 200x le kell írni 1-1 kódot, ha kellő részletességgel meg akarja mutatni az ember. Egyelőre arra gondoltam, hogy beszórom egy verziókezelőbe, és minden lépést committálok, aztán majd kitalálom, hogy mi lesz. Pl egy diasorban már elképzelhető, hogy le lehet adni normálisan.