Többszintű hierarchikus HTML struktúrák fölé építhető moduláris Composit szerkezetek és működési mechanizmusaik.

A lentebbiekben nem kevesebbre vállalkozom mint, hogy ismeretterjesztő formában, a laikus olvasónak is közérthetően elmagyarázom, és az ábrák segítségével szemléletessé teszem az általam megvalósított dinamikus navigáció felépítését, és a működés főbb aspektusai mögött álló programozási megoldásokat, a PROGRAMMINTÁKAT.
A weboldalakon akkor találkozhat ilyen hierarchikus szerkezetekkel a felhasználó, például, amikor valamilyen harmónika szerű oldalnavigációban fentről lefelé, egyre mélyebb szintre navigál, vagy – bár ezzel valószínűleg nincs tisztában – egy űrlap (form) részeit tölti ki.
Mindkét rendszerre nagyon jól illeszkedik a Composit programozási minta, de az űrlap, és a hozzá tartozó elemek tekintetében sokkal több metódust, és sokkal bonyolultabb összműködést kell megvalósítani, ezért a bemutató céljának inkább megfelel, ha példaként a harmónika navigációt veszem.
A képek, és az egyes részek taglalása fentről lefelé logikus sorrendet követ, és a részek egymásra épülnek, ezért érdemes folyamatosan haladni, akkor is, ha a bemutató leglátványosabb része az oldal legalján található!
A hozzáértők könnyű eligazodását segíti, hogy a kódot logikus neveket viselő fájlokra bontottam, és egyes helyeken annotáltam is. A fő cél mindenhol a közérthetőség, hogy bemutassam, nagyon bonyolult dolgokról is lehet szemléletesen beszélni, és ezzzel egyben választ is adok az ITT elmondottakra. Ugyan akkor az (angol!) szakzsargon pontos kifejezéseit is mindig megadom zárójelben!

Mindenek előtt, ismerkedj egy kicsit a dinamikus navigációs elemmel. Navigálj benne különböző részekhez, nyisd ki – csukd össze, majd mozgasd az oldal különböző részeire. Figyeld meg mi történik, ha nyitott állapotban átvonszolod az oldal túloldalára, vagy ha megpróbálod az oldal határain túlra vinni. Amikor csak vertikálisan van nyitva, kattints a fő navigáció valamelyik elemére, aztán meg nézd meg a le – föl, balra – jobbra billentyűk hatását, vagy üss rá az Enter gombra.

hagyomásnyos composit struktúra

A Klasszikus Composit szerkezet bemutatása

Mindenek előtt kis kitartásodat kérem, ha elsőre úgy éreznéd, nem tudod miről, vagy miért is kezdek a lentebbiekről értekezni. Ígérem, hogy amikor fentről a negyedik képhez, és az ott elmondottakhoz érsz, minden a helyére kerül majd! Legelőször is az a célravezető, ha röviden megismerkedünk a sokszintű, hierarhikus struktúrák - mint amilyen ez az összetett navigáció is - mögötti programozási mintának, a Compositnak az általános felépítésével. Aztán ebből levezetem, ehhez képest bemutatom az általam végrehajtott változtatásokat, és a megvalósított komplex működési mechanizmusokat.

A Composit struktúra – amint azt az összekötő vonalak jelzik, szülő – gyerek objektumokból, hierarhikusan épül fel. A valóságban minden szülő objektum rendelkezik egy tároló rekesszel, és ebben tartja a hozzá tartozó gyerek objektumokat, de ez egy egyoldalú viszonylat, mert a gyerek objektumok viszont nem „tudnak” a szüleikről, vagy hogy őket egyáltalán tárolják valahol!

A piramis szerkezet többfajta, rendszerint 2-3 különböző Composit objektum típus példányainak az alá-fölé rendelésével jön létre, a csúcson mindig egy fő elemmel, amely mintegy felülről össze fogja, koordinálja az egészet. Figyeld meg a szerkezet elágazásvégein , véghelyzetben lévő, levélnek nevezett (leaf) objektumokat is, melyeket a képen világoskék gömbökkel jelöltem. Ezek két dolog miatt fontosak. Egyrészt nekik soha sincsenek további gyerek objektumaik- legalább is a klasszikus modelben - és ami a lényeg, hogy a valódi cselekvés legtöbbször rajtuk váltódik ki, míg a felsőbb szintekről a felmenő szülő objektumok csak a csúcstól lefelé továbbítják feléjük a függvény hívásokat. Másként mondva: típusra való tekintet nélkül minden Composit objektum ugyan azokkal a metódusokkal rendelkezik – a csak rá jellemzők mellett! – csak a megvalósítás teljesen más a felső, szülői, és a levélszinteken!

a notify metódus

A notify metódus bevezetése, és használata

A baloldalt látható klasszikus rendszerben az egyes metódusok fentről lefelé, a szülők felől, a gyerekek irányába, ÉS egymástól függetlenül kerülnek meghívásra, az éppen kiváltani kívánt funkció szerint. Erre utalnak a különböző színű nyilak. Az Én megoldásomban ez kiegészül a notify (értesít) metódussal, amelyen keresztül lehetőség nyílik egyszerre több metódus kötegelt, paraméterezett meghívására, akár több elemen is. Ami talán még ennél is fontosabb az, hogy a notify metódus belső terében a szerkezet minden eleme megfelelteti a kapott információt az ő tetszőleges feltételeinek, és az eredménynek megfelelően, adekvátan képes reagálni. Másként mondva: minden szinten, a spontán, vak hívás – tovább adást, célzott cselekvés válthatja fel. Ezt a fajta elágaztatást hívják, egyébként CHAIN OF RESPONSIBILITY –nek, felelősség sornak!

a composit faktory minta

A Composit struktúra létrehozása a már meglévő HTML szerkezet leképezésével

A Composit struktúrát – mint az összes többi absztrakt objektumokból állót – az alap HTML szerkezet fölé – mellé építjük, hogy rengeteg új funkciót adjunk hozzá. Mármint a HTML-hez! Másutt eddig csak arra láttam példát, hogy az absztrakt objektum példányokat, a szülő – gyerek objektumokat hozzák először létre, és ennek során, a program mesterségesen legyártja azt a HTML elemet is, ami az adott objektumhoz tartozik. A következő lépésben aztán a gyerek Composit objektum példányt hozzáadják a szülőjéhez, amely a tároló rekeszébe elrakja azt, és egyúttal tovább építi magát a HTML struktúrát is, míg végül, ilyen módon, LÉTRE JÖN – mondjuk – a baloldali oldal navigáció.
Soha nem értettem miért nem fordítva történik mindez, vagyis miért nem a természetes HTML hierarhia leképezésével hozzák létre az egyes HTML elemekhez a hozzájuk tartozó Composit objektumokat, és végül magát a Composit piramist, amikor ez kínálja magát, és meglepően egyszerű módon véghez lehet vinni!

A képen azt látjuk, ahogy a walk_the_dom_recursive függvény végig ássa magát valamilyen létező HTML struktúrán, és eközben, sorban minden HTML elemet a process_nodes függvénynek továbbít, több más paraméterrel együtt. Az ott zajló folyamatok a képről leolvashatók, de ami még nagyon fontos az, hogy minden frissen képzett Composit példány egy-egy hivatkozást őriz a szülőjére ÉS a piramis csúcsán trónoló fő Compositra is! Ennek kiemelt jelentősége van sok magas szintű funkció megvalósításában!
Ezt a fajta, feltétel szerinti objektum képzést hívják FACTORY (GYÁR) programozási mintának!
Hogy a laikusok is ízelítőt kaphassanak a javascript programozásból, és mivel egy nagyon kicsi, kompakt kódrészről van szó, amelyben a részek csak egymást használják, ezeknek a függvényeknek a részletes elemzését ITT is hozzáférhetővé tettem!

a módosított composit struktúra

A dinamikus navigáció Composit struktúrája

A képen a dinamikus navigáció keretében konkrétan megvalósított Composit struktúrát láthatjuk a HTML szerkezetre vetítve. Látható, hogy közvetlenül a Top_Composit elem alatt a fő navigáció minden egyes (HTML) eleméhez tartozik egy absztrakt Composit egyedpéldány, mint ahogy az eggyel bentebbi szinten, az egyes nyitogatható fülekhez is. A valóságban is a Composit elemek megnyitásakor – figyeld a fehér, és a zöldes panelokat – megjelenítjük , vagy elrejtjük a hozzájuk tartozó nagy tároló HTML (elemeket), táblákat! A képen a fő navigáció első eleme, és alatta is az első fül lett megnyitva, míg a korábban világoskék gömbökkel reprezentált vég-, levél composit objektumok egyelőre mind zárva vannak.
Annyiban más a levélhelyzetben lévő objektumok szerepe, hogy itt nekik is lehet tetszőleges számú további gyerek objektumuk! Tehát a kinyitott szem alatt tobábbi zárt szemmel jelölt részeket láthatsz, esetleg, és így tovább.

egyszerű nyitás-zárás

Egyszerű nyitás – zárás

Korábban láttuk, hogy minden Composit példány a képzésekor megőriz magán egy-egy hivatkozást a szülő Composit elemre, illetve a piramis csúcsán lévő Top Composit elemre is. A képen az figyelhető meg, mi történik, amikor rákattintunk egy zárt Sub_Composit elemre ( a fentebbi képen a világoskék hátterű leaf elemek, amikor a zárt szem ikon látható mellettük). Nos, az adott levél megnyitja önmagát, illetve a szülőjére mutató hivatkozáson keresztül meghívja annak a close_siblings (testvérek_zárása) metódusát. A többit leolvashatod a képről..

a komplex open-up metódus

Kereszthivatkozások – dinamikus linkek használata

A baloldali kép már egy sokkal magasabb szintű funkció megvalósítását mutatja, konkrétan azt, hogy ha a szerkezetben bárhol egy olyan linkre kattintok, amely a struktúrának egy éppen rejtett részére mutat, akkor nem csak hogy automatikusan ott nyílik ki a navigáció, ahol kell, hanem ráadásul az ott megjelenő <VISSZA> link címébe dinamikusan beíródik az a belső cím, ahonnan oda jöttem. Tehát, ha nyolc különböző helyről belinkelem ugyan azt a részt, akkor is mindig vissza tudok menni az eredeti kiindulási pontomhoz.
1.) Amikor a szövegben egy linkre kattintok a Composit egyedpéldányon, a Top_Composit elemre mutató referenciát használva, meghívja a csúcson lévő főelem notify metódusát, 2.) amely metódus a lentebbi elemeken - mint láttuk- kódelágaztatást tesz lehetővé.
3.)Ha a képen lefelé követed az egyes szinteken átfutó piros vonalat, akkor ahhoz aa Composit elemhez érsz, jelen esetben ez egy levél helyzetben lévő elem, de lehetne akármi, amelyikben a belső feltételvizsgálat pozitív eredménnyel zárul! Lást, fentebb a notify metódus használatáról szóló részt!
Ide akarok menni, azt szeretném, ha itt nyílna ki az összecsukott szerkezet! Itt a már részletezett dinamikus címírást követően, az adott elem felfelé, csak a korábbi close_siblings hívással ellentétben most folyton tovább, egészen a legfelső szintig meghívja, meghívatja a fölötte álló szülő compositok open_up (nyilj ki) metódusát. 4.)
Itt tehát arra is példát látunk, hogy a Composit szerkezet – a klasszikushoz viszonyítva – fordított irányban is működhet, amennyiben megteremtjük ennek a feltételeit!

a Publisher programminta

A különböző osztályok közötti adatcsere megvalósítása

A dinamikus navigáció használata nagyon sok különböző funkció megvalósítását követeli, melyeket érdemes logikusan összetartozó blokkokba, osztályokba szervezni. Ezek közül eddig kizárólag a baloldali, összetett Composit rendszerről esett szó, de – mint azt a képen is láthatod – még további két osztály felel a fennmaradó más funkciókért! Az általam követet logika szerint a navigáció megvalósításához, és a szerkezet egyes részeiben elhelyezett tartalmak felfedéséhez és elrejtéséhez szükséges kód került a különböző Composit osztályokba (Nav_Abstract , Top_Nav_Composit , Nav_Composit, Sub_Nav_Composit). Korábban a process_nodes függvény bemutatásakor csak hivatkoztam a Composit egyedpéldányok legyártatására. Nos, a valóságban a függvény az utóbbi hárommal képezteti a composit egyedpéldányokat, míg az első – mint a neve is mutatja – a többi számára szolgál háttér bázisul, úgy hogy jól kistafírozza őket minden jóval, amit nem kell külön, specifikusan megvalósítani.

Az open_close osztály a horizontális – vertikális nyitás – záráson túl, a helyén, illetve az oldal határain belül tartja a navigáció külső HTML elemét, és ezáltal az egészet is, korrigálja a nyitás – záráskor bekövetkező pozícióbeli elcsúszásokat, bal-jobb nézetre vált, stb, stb. A Dragable osztály pedig a navigációnak az oldalon történő mozgatását teszi lehetővé. Még gondos tervezés mellett is, amikor összetartozó funkciók szerint alakítom ki az egyes osztályokat szükség van azonban az osztályok közötti adatcserére. Képzeljük el a dinamikus navigációnak azt az állását, például, amikor csak függőleges irányban van nyitva, és az egyik látható fő navigációs elemre kattintunk. Ha az open_close osztály nem lendülne akcióba, nem látnánk az újonnan mutatott tartalmat, mert a külső elem horizontálisan zárva maradna, és mi azt hihetnénk, hogy nem történt semmi, pedig dehogy nem, csak rejtve maradt a szemünk elől! Tehát valahogy üzenni kell az open_close osztálynak, hogy ugyan, nyisson már ..
Erre a célra találták ki az OBSERVER , vagy más néven PUBLISHER — SUBSCRIBER programmintát!
A lényege, hogy úgy működik, mint az újságkiadó cég az előfizetőivel. Amikor megjelenik a lap legfrissebb száma, már továbbítja is azt mindegyikhez! A képen felül két ilyen Observer is látható, és a bennük lévő narancssárga sáv mutatja, hogy az open_close osztály mindkettőbe feliratkoztatta egy – egy metódusát, hogy egyrészt a dinamikus navigáció felől információt kapjon, másrészt arról is értesüljön, amikor a Scriptaculous könyvtár Draggable osztálya a vonszolás végeztével elengedi a navigációt ( szükséges pozíciónálás, bal – jobb irányváltás, korrekciók..). Figyeld a különböző színű nyilakat!

A Bridge programminta

A modularitás további módjai: a Bridge (Híd) programminta

Minden jól megírt, objektum orientált kód moduláris szerkezetű, azonban a modularitásnak még több aspektusa, és rengeteg előnye létezik. Ha végig követted a fentebbi példákon keresztül elmondottakat, akkor láthattad, hogy a különböző Composit egyedpéldányok környezetfüggően, – mindig az kívánt Composit modul (osztály) meghívásával – jönnek létre. A számos szükséges funkciót egymástól különálló osztályokba szerveztem, hogy logikus, független egységeket alkossak, és az így képzett osztályok metódusai sosem közvetlenül hívják meg egymást, ami az egyik súlyos objektum orientált hiba (tight coupling), hanem külső közvetítő osztályon, a Publisher-en keresztül cserélnek adatokat. Egy dolgot nem mutattam még meg, és ez az osztályoknak a felhasználói felülettől- a HTML gombokról, linkektől, form elemektől stb- történő leválasztása.
Erre a célra találták ki –például – a BRIDGE (HÍD) programozási struktúrát.

Most egy kicsit előre ugrok a kicsit lejjebb következő gyakorlati részhez, és a képen azokat az előre – hátra, illetve törlés gombokat tüntettem fel, amiket Te is mindjárt használhatsz majd az előzmény listában az előre – hátra léptetéshez. Látszik, hogy a gombokhoz eseményfigyelőként ugyan azt a köztes függvényt rendeltem, úgyhogy amikor bármelyik gombra kattintasz, mindig ez a függvény kerül meghívásra, és aztán ez hívja meg a szükséges comand_stack metódust az eredeti HTML elem id azonosítójával. Kérdezhetnéd, mi értelme közbe iktatni még egy lépést, és a válasszal már egyben át is térünk a modularitás előnyeinek általános taglalására: Nos, az objektum orientált programozás elsőszámú szabálya így hangzik: „Program for an abstraction not for an implementation.” – magyarul, saját szabadfordításomban: – „ A programírás eredménye egy általánosan alkalmazható, rugalmas megoldás legyen, amit könnyen, sok egyedi helyzethez tudsz igazítani, ne pedig egy rugalmatlan, egybeöntött, csak egyetlen feladat megoldására alkalmas kimenet. Vesd össze ezt az ITT elmondottakkal! A HTML eseményfigyelők a webböngésző által generált event (esemény) objektumot kapják bemenetül, amit másként nem tudok előállítani. Ha ez az esemény objektum lenne a comand_stack metódusok bemenete, akkor nem tudnám őket a webes felhasználói felülettől elválasztva tesztelni, mondjuk a javascript konzollal (unit testing), szoros kötésbe hoznám őket (closely knit/ bound) a HTML elemekkel. A híd közbeiktatásával viszont, bármikor be tudok írni egy id azonosítót a konzolba, és előre – hátra tudok léptetni a tárolt comand elemek között – amint azt mindjárt Te is kipróbálhatod! A comand programozási minta tárgyalását lásd a gyakorlati rész után!
A tesztelésen túl, további előny a programozók közötti munkamegosztás lehetősége is. Ha különálló blokkokból áll a kód, akkor csak abban kell megállapodniuk, milyen részekre bontják, milyen osztályokba szervezik a funkciókat, és azok milyen módon, és formában cserélnek egymással adatokat ( interfaces). Ezt követően minden programozó a saját stílusát követheti a Neki jutó rész megírása során, és elég, ha u.n. csonkokat (trunk), vagyis egyszerű helyőrző függvényeket ír a többiek számára, amelyek az ő egysége által majd nyújtott kimeneteket produkálják, amíg el nem készül a tényleges osztályokkal.

Előre
Vissza
Törlés
Bekapcsol

Modularitás a gyakorlatban

Elérkeztünk végre ahhoz a részhez, amit a legelején is ígértem, vagyis, hogy mindenki saját maga is leellenőrizheti, kipróbálhatja mit is jelent a modularitás a gyakorlatban! Három olyan lehetőséget is mutatok, amit akár egy elemes szekrénysortól is elvárhat valaki:
egyrészt, tetszőlegesen előre – hátra lehet léptetni az alkalmazást egy korábbi, vagy későbbi állapotra, ez következik elsőként, másrészt – és szerintem ez még érdekesebb!– tetszőleges számú részekkel tovább lehet bővíteni a navigációt úgy, hogy közben szabadon meg lehet határozni az új rész címét, cimkéjét, tartalmát és megjelenését.

Előre – vissza léptetés.

Először a baloldali felső szövegdobozra, és a hozzá tartozó gombokra lesz szükséged. Figyeld meg: ha az alul lévő gombra kattintasz, akkor annak bekapcsolt, illetve kikapcsolt állásai között tudsz váltogatni. A jobb oldalán elhelyezkedő gombok pedig az előzménylistában történő léptetéshez, valamint annak törléséhez szükségesek.
Ha most bekapcsolt állapotba hozod a dobozt, vagyis elkezded felvenni a történteket, majd minden lehetséges módon használni kezded a navigációt: ide – oda hurcolod az oldalon, nyitogatod – csukogatod, vagy össze – vissza navigálsz benne, akkor minden alkalommal egy újabb elem fog megjelenni a dobozban! Az egyes színek, és a feliratok pedig, a változtatás típusára, és milyenségére utalnak. Ha már jó sok sor megjelent, elkezdheted használni az <ELŐRE> — <HÁTRA> gombokat, hogy az adott irányban lépegess. Ha pedig a gombok helyett egy tetszőleges linkre kattintasz, azonnal az adott link által jelölt állapothoz ugorhatsz! Próbálj karakteres változtatásokat véghezvinni, amelyekre emlékezni fogsz, például, egy navigációs lépést követően cipeld át a nyitott elemet a túloldalra, majd zád be, és azt követően nyisd ki újra. Arra is ügyelj, hogy a dinamikus navigáció sose takarja ki a link mezőt(history list), vagy a menügombokat, mert akkor majd nem férsz hozzájuk!

Bevitel
Cseréld — fűzd

Új kategóriák – alkategóriák hozzáadása, kereszthivatkozások beillesztése, a megjelenés modulonkénti beállítása.

A következő rész adja a gyakorlati bemutató lényegét, az alcímben megfogalmazott funkciók bemutatását, és ennek megfelelően három videóban, sorra veszem azokat a lépéseket, melyekkel ezek megvalósíthatók.

A videókban látható lépések

  • A navigáció változtatható részének a bemutatása
  • A már meglévő menüelemek tartalmának a cseréje
  • Új almenük hozzáadása
  • Kereszthivatkozások elhelyezése az új menüelemekben, azok helyes működésének az ellenőrzése
  • A menüelemek külalakjának szabad megválasztása, a változások törlése
  • Az új elemeknek a rendszerbe történő teljes integrációjának a szemléltetése

A dinamikus navigáció kibővítése újabb modulokkal, az egyes részek tartalmának szabad változtatása.

Mindenek előtt nézzük meg, hogyan lehet a navigációhoz újabb részeket adni, a bennük elhelyezett tartalmat lecserélni, vagy továbbiakkal bővíteni .
Ez azt hivatott jelezni, hogy a szerverről lekérdezett adatcsomagok tartalma szerint, akár mikor tovább bővíthetem a struktúrát.
Természetesen a részek redukálásához, az egyes már beépült modulok elvételéhez is rendelkezésre áll minden szükséges háttér, csak ezt a funkciót most nem tettem elérhetővé..

Magas szintű funkciók a beépülő modulokban

Az elméleti részben kifejtettem mennyiben tér el az általam használt Composit struktúra felépítése, és nem mellékesen annak létrehozása a klasszikustól. Nos, a composit egyedpéldányok kontextustól függő képzése, a szülő – gyerek példányok egymáshoz rendelése, nem csak az egész HTML szerkezet bejárása során lehetséges, hanem a további részek hozzáadásakor, egy – egy modulra vonatkoztatva is. Erre ad gyakorlati bizonyítékot a kereszthivatkozásokat lehetővé tevő – korábban már sematikusan bemutatott open_up metódus zökkennőmentes működése.

Az egyes modulok megjelenésének változtatása

Miután új modulokat adtunk a már meglévő struktúrához, és láttuk, hogy ugyan azokkal a funkciókkal rendelkeznek, mint a szerkezet már meglévő részei, itt az ideje, hogy azt is megmutassam: nem csak a tartalmat tudom részenként szabadon változtatni, hanem ez a megjelenésre is igaz.
Ennek ott van jelentősége, hogy a szerverről lekérdezett adathalmazban az egyes modulok tartalma mellett azok megjelenését is meghatározhatom, illetve egymástól függetlenül, szabadon változtathatom.

A Comand programminta

Az előre — vissza léptetés megvalósítása: A COMAND (PARANCS)minta

Az előbb láttad, amint az előzménylistában újabb –és –újabb sorok jelentek meg, ahogy a navigációt különféle módokon használtad, és a megjelenő belső címekkel Te magad is új kereszthivatkozásokat hoztál létre. Az ezt lehetővé tevő szerkezetet hívják a COMAND (PARANCS) programozási mintának, és ez az egyik legösszetettebb programozási struktúra. Mielőtt a működését taglalni kezdenénk, vessünk egy gyors pillantást a képen baloldalt ábrázolt comand_stack objektumra, ami valójában a SINGLETON (EGYKE) programozási mintát valósítja meg a gyakorlatban. Ez is egy egyszerű minta, mert annyit jelent, hogy egy name space-t (önállóan címezhető név teret) képez, ami köznapi nyelven annyit tesz, hogy mint egy csomag, egységbe foglalja a futtatható metódusait, és a futtatásukhoz szükséges változókat. Amikor azokat a tevékenységeket végezted, amire fentebb bíztattalak, vagyis, navigáltál, nyitogattad az elemet, vagy ide – oda cipelted az oldalon, a comand_stack erről mindig értesítést kapott, sőt a stack rekeszében erről el is tárolt egy zárványt (closure)! A magyar kifejezés nem utal a lényegre, és elég félrevezető, ezért inkább úgy képzeld ezt el, mint egy eltett függvény teret, egy lezárt kapszulát, amibe mindig bezárta a következőket: egy hivatkozást annak az osztálynak a metódusára, ami az aktuális tevékenységet végezte (cipelés, nyitásért, vagy a navigációért felelős metódus), és minden paramétert ami a cselekvés pontos végrehajtásához kellett. A stack változóban tárolt closure-ket, zárványokat más színnel jelöltem aszerint, hogy melyik osztály metódusát fogják futtatni, amikor később bármikor meghívjuk őket. A képen azt láthatod, amint egy ilyen eltett függvény teret, kapszulát az előre – vissza léptetésnek megfelelően éppen meghívsz!

Pár szó az állapot visszaléptetésének nehézségeiről.

Alapvetően kétféleképpen lehet egy objektum – most egyszerűsítsük ezt a mozgatható – nyitogatható, stb, HTML navigációra – állapotát egy előzőre visszaállítani: vagy rögzítem a kiindulási helyzetet, például az oldal betöltésekor elfoglalt pozícióját, azt hogy a navigáció melyik részét mutatta, illetve nyitva – vagy zárva volt –e horizontálisan és vertikálisan, és aztán minden egyes változtatás során sorban elteszek egy zárványt, egy lezárt kapszulát az aktuális változás mennyiségére – esetleg minőségére vonatkozó paraméterekkel, valamint a végrehajtó metódusra mutató hivatkozással, amit a fentiek szerint később bármikor meg lehet hívni. Az adott lépést ismét végre lehet hajtatni!
A visszaállítás legelső lépéseként aztán mindenek előtt helyreállítom a kiindulási helyzetnek megfelelő állapotokat, majd végig futtatom, egyenként, sorban meghívom az eltett függvény tereket, kapszulákat, egészen az utolsó előttiig, vagy a sorban rákövetkezőig, mint ahol éppen állok, aszerint, hogy előre, vagy hátra léptetek –e! Ennek a módszernek a hátulütője, hogy leginkább valamilyen egyszerű dolgot végző metódust lehet sorban futtatni vele, komplexebb dolgokat nem képes megfelelően kezelni. Például, ha az alkalmazás, Ajax hívásokon keresztül, több lépésben adatokat ír, vagy töröl különböző adatbázis táblákból a szerveren, akkor rengeteg mindent biztosítani kell ehhez, és egyáltalán, a sor elején lévő állapotot biztosan nem tudom egy lépésben visszaállítani, ha a közbeeső lépések mindegyikében sokoldalú, gyakran az előzmények sikerétől is függő, elágazó változások mentek végbe!
Nos, erre találták ki a másik módszert, ami az általunk várt módon, mindig csak az eggyel előző állapotra lép vissza. Ilyenkor nem zárványokat (closure) mentünk el, hanem komplett kis objektumokat, amelyeknek van egy a változást kiváltó metódusa, és egy ezzel ellentétes is, amelyik vissza állítja a vele ellentétes metódus által végzett változásokat, bármit jelentsen is ez a gyakorlatban! Nyilván ennek az utóbbinak a megvalósítása lényegesen nehezebb, és egyáltalán nem olyan látványos, mint az oldalon láthatóé!

Vidd