2005-11-30

Eclipse, Taconite

Hohó, két post egy nap alatt!

Szóval először is felraktam ma az 1.5-ös Firefox-ot aminek a Clear Private Data funkciója nagyon tetszik.

Kipróbáltam a Taconite-ot is ami szintén megfogott, csak kissé kényelmetlen volt highlight support nélkül jsp-ket írni, úgyhogy nekiálltam Eclipse plugin-t keresni. Találtam is, a WTP -t. Namost ha ennek csak a webes részét installálom akkor a jsp-ket nem highlight-olja hanem csak a html-t, css-t, xml-t meg még egy-két dolgot. A másik, hogy nem akarta az igazságot ezért installáltam gyorsan egy 3.1.1.-es Eclipse-t. Itt már működött, viszont kellett még hozzá installálni vagy 3 plugint. (JEM, EMF meg ki tudja mi...)

Most próbálgatom. Tetszik, már össze is haverkodtak a Taconite-tal. Highlight-ol mint a kisangyal, jönnek fel a popupok a lehetséges dolgokról, úgyhogy lehet haladni ezerrel. Egyetlenegy kis bánatom van, hogy nem támogatja a 4.0-ás JBoss-t. Ha J2EE projektet akarok csinálni 3.2.3 a legfrissebb amit ismer, és a projektcsinálás meg is bukik egy ponton amikor nem találja a jboss-boot.jar-t.

Közben volt egy downgrade-elés 3.2.6-os JBoss-ra és ismét megpróbáltam J2EE projektet létrehozni ugyanekkora sikerrel. Ennél régebbi JBoss-t már nem vagyok hajlandó feltenni. Generikus J2EE projektet is megpróbáltam létrehozni, akkor meg az annotation engine-be kötött bele, merthogy XDoclet-et szeretett volna. Azt hiszem az XDoclet már eléggé kifutóban van a JDK5 annotációi miatt úgyhogy ebbe már fölösleges (újra) belekezdeni. Akkor inkább megvárom a következő (rendes) verziót ebből az Eclipse pluginből.

AjaxTags vs Taconite

Belekukkantottam ennek a két frameworknek a kliensoldali javascript forrásába és azt kell hogy mondjam, a Taconite korrektebbnek néz ki. Az AjaxTags-ban külön tag-eket kezdenek el fejleszteni (taglib) -ez eddig rendben is van. Viszont a .js fájlban direktben benne vannak a komponensek kliensoldali kódjai. Mindegyiknek külön paraméterezése van vagy mi, ami abszolút nem tetszik nekem. És ha lesz 600 komponens akkor 1 megás lesz a .js fájl? A Taconite jóval általánosabb és körültekintőbb megoldásnak tűnik így első ránézésre.

Egyébként van még az AjaxAnywhere ami szintén egy open source project, de nem szorosan ide tartozik mert hagyományos webappokat lehet átírni vele ajax-osra. Azért kicsit idetartozik, mert biztos általános megoldásai vannak. Olyasmit láttam, hogy ki kell jelölni a jsp-ben (taglib) hogy melyik rész lecserélhető ajax-szal. Jó gondolat.

Láttam két céget, mégpedig a Backbase-t (Amszterdamban székelnek) és a Laszlo Systems-et akik foglalkoznak kommerciális ajax megoldásokkal. Úgy nevezik hogy rich web applications. A Backbase szimpatikusabb, a Laszloéknak kicsit körmönfontak a demói.

2005-11-28

GPL flame

Jó kis flame alakult ki az Index Programozás fórumában az open source programozásról illetve az ezzel kapcsolatos megélhetési lehetőségekről. Szokás szerint elbeszélnek az emberek egymás feje mellett, de egyébként van benne igazság. (Attól hogy valami "open source" még nem következik belőle hogy GPL.)

A GPL a totál nyílt cucc, amibe bele van építve azért sem lehet pénzt kérni. Ez késdöfés azoknak az oldalába akik olyan szoftvert fejlesztenek amiből van hasonló minőségű GPL-es cucc. Vagyis rákényszeríti őket hogy jobb minőségű szoftvert és/vagy supportot adjanak a termékükre. Abból a szempontból jó ez a világnak, hogy versenyt teremt. Gyér minőségért nem lehet pénzt kérni.

2005-11-23

ASP.NET oldal életciklus

Még régebben utánanéztem egy ASPX oldal életciklusának és lefirkantottam. Íme:

"Bejön a HTTP kérés az IIS szerverre. Ez a HTTP pipeline-n (HttpRuntime, IHttpHandler, IHttpHandlerFactory, ProcessRequest()) keresztül eljut az oldalhoz. Minden .aspx URL-hez ugyanolyan nevű aspx tartozik. Amikor az URL első alkalommal meghívódik az aspx forrás lefordítódik és egy assembly készül belőle.

Az oldal ProcessRequest metódusa hívódik meg.

Felépíti az oldalon található kontrollok hierarchiáját.

Init esemény generálódik.

Feltölti a kontrollokat a viewstate-jeikkel.

LoadPostData hívódik meg azoknál a kontrolloknál amik implementálják a IPostBackDataHandler-t. Itt még NEM szabadna eseménykezelőt indítani, mivel a viewstate még nincs feltöltve! Ehelyett, ha a LoadPostData true-t ad vissza később meg fog hívódni a RaisePostdataChangedEvent metódus.

Load esemény generálódik. Ekkor már be vannak állítva a kontrolok a kliensoldali interakcióknak megfelelően.

Ha van ilyen, meghívódik az eseménykezelő ami miatt a postback keletkezett. Ez az a bizonyos RaisePostDataChangedEvent metódus.

PreRender esemény generálódik. Ide még lehet olyan logikákat rakni ami az eventkezelés után és a renderelés előtt szükséges.

Aztán rendering módba kerül, legenerálja a HTML kódot és elküldi a választ.
Unload esemény generálódik.

Ha dupla request keletkezik, pl. egy gomb kétszeri megnyomásával, akkor az szépen beáll a queue-ba és végrehajtódik mindkét kérés."

2005-11-15

GUI-t mindenki tud tervezni?

Első munkahelyemen telefonokra fejlesztettünk szoftvereket és jó kis alkalmazástesztelő csapat volt, akik minden fölösleges gombnyomásba vagy kihasználatlanul hagyott területbe belekötöttek -és igazuk is volt. Baromi hosszú könyveket tudnak írni gui fejlesztésről, ami mondjuk kicsit túl van spirázva de azért van benne igazság.

Dehát a számítógép nem telefon, mindent lehet. Lepedő méretű üres helyek, 10 klikkelés ha eggyel is meg lehet csinálni valamit. Jobb esetben a fejlesztők legalább agyalnak rajta valamennyit hogy a gui milyen módon működjön logikailag, de a megrendelő kitalál egy neki tetsző esetenként dilettáns megoldást anélkül hogy továbbgondolná. Rosszabb esetben a fejlesztőnek sincs érzéke a témához. Nem is tudom mi kell ehhez, talán empatikus készség és egy kis kreativítás ötvözete.

A címben feltett kérdésre a válasz: nem.

2005-11-11

Ajaxos fejtegetés

Kezdetben volt a HTML, ami az SGML egy változata. A céljának -hogy olvasható legyen a gazdag dokumentumok forrása- megfelelt, viszont ahogy rájöttek a programozók a fastruktúra előnyeire kijött az XML -az SGML egy szigorúbb válfaja- és a HTML-nek is változnia kellett. Ebből lett az XHTML. Az XHTML-t könnyű kezelni a sok XML eszköz miatt. Dinamikusan lehet szerveroldalon DOM-ot összerakni, parse-olni is könnyebb, stb stb. Olvashatóbb is egyébként.

Ezzel párhuzamosan fejlődött a kliensoldali scriptelés is. Az XHTML elterjedésével a script-ek is egyre merészebben módosítgatják a DOM-ot és az XmlHttpRequest megjelenésével már a lap újratöltése nélkül is tudnak kliens-szerverinterakciót kezdeményezni ami esetleg a lap (DOM) csak egy részének megváltoztatását eredményezi.

Abszurd az eset, mert az először letöltött dokumentumnak esetenként látszólag egyáltalán nincs köze a browserben ténylegesen megjelenő oldalhoz. Az oldal forrása pedig már nem igazán átlátható. Tehát az (X)HTML szerepe teljesen megváltozott. Az egyszerű szövegszerkesztő már rég nem elég egy oldal szerkesztéséhez és most az XmlHttpRequest -és így a fokozott kliens-szerver kooperáció- megjelenésével a mostani kérés-válasz modellre épülő eszközök (asp.net, jsp, szervletek, php) túl primitívek a feladat megoldásához.

Éppen ezért fogott neki több szervezet is a különféle AJAX frameworkok fejlesztésének. Na majd meglátjuk melyik a "jobbik"...

2005-11-04

Active Record antipattern

Update 2009.05.22: Szerencsére ma már vannak jól kialakult perzisztencia framework-ök (a JPA-ról nem is beszélve) és a kultúrált programozók DAO-kkal dolgoznak, de nemrég találkoztam olyan emberrel aki éles projektben komolyan használni akarta ezt a design pattern-t. Ráadásul egy másik postban más okból is linkeltem erre a rövid kis agymenésre, szóval kicsit megcizellálom.

Szóval az Active Record design pattern dióhéjban arra épül, hogy az objektum maga tudja, hogyan kell őt beolvasni vagy legalábbis kimenteni valami adatbázisba. Tehát van save metódusa, ilyesmik.

Első probléma, hogy rögtön kell az objektumba injektálni valami adatbázisközeli logikát, ami másrészről nem jó helyen van ott, hiszen fölösleges függőséget hoz be a domain modell entitásaiba. Ha nem elég flexibilisre van megcsinálva ez a logika akkor a hordozhatóságnak annyi, pl. nem lehet kicserélni alatta a perzisztencia réteget. Van erre két megoldás: egyik hogy örököljük ősosztályból a logikát, nade ekkor is felülről (még rosszabb) betámadnak az implementációs részletek a domain modellbe. Ebben az esetben ráadásul el kell lőni az egyetlen öröklési lehetőséget (Java, C#) az implementációs részletek miatt. Na és mi van ha még a domain modell miatt is kéne örökölni? Pech. Másik megoldás a logika delegálása. Igen, ez működhet csak ügyelni kell rá hogy az objektumokhoz hozzá legyen cuppantva a logika ami kimenti őket.

Második probléma, hogy ha ezeket az objektumokat neadjisten másra is használni kell, felbugyoghatnak a szervíz rétegből a GUI logikába, félreeső modulokba. Például valaki véletlenül mond ott egy delete-et és szevasz aktív rekord - automatikusan mindenki számára publikálja a műveleteket. Egy jól leválasztott szervíz réteg esetén jól meg lehet határozni, hogy melyik modul milyen interfészt kap meg.

Hozhatnék még fel ilyen kérdéseket, hogy vajon minden adatbázis rekordhoz van egy aktív rekordunk a memóriában? Pazarlás. Minek? Stb.

A régi posthoz még annyi bevezető, hogy néha (ez már WTF kategória) a konstruktor meghívásával generálják az adatbázis rekordot, tehát a new Person('pcjuzer') valóban adatbázis műveletet von maga után. Csakhogy...

Innen pedig a régi post:

A konstruktornak van egy olyan tulajdonsága, hogy a lefutása után csakis egy újonnan inicializált objektum referenciáját tudja visszaadni. Tehát sem null-t, sem a hívás előtt létező objektum referenciáját nem tudja visszaadni.

Bevett gyakorlat, hogy egy objektumpéldányhoz egy adatbázis rekord tartozik. (Egyébként nagyon okos neve van a megoldásnak: Active Record. Annyira okos, hogy még céget is elneveztek róla.) Ha ezt az objektumpéldányt a konstruktorral akarjuk kiolvasni az adatbázisból, akkor több konstruktorhívás több példányt fog eredményezni ami ugyanarra a rekordra mutat. Ez egyrészt erőforrászabáló másrészt inkonzisztens állapotot lehet előidézni vele, ha a két példányt megváltoztatjuk és ezután visszaírjuk az adatbázisba.

Ehelyett factory metódust vagy osztályt kell használni, ami egy pool-ból kiveszi a már egyszer feltöltött rekordok objektumait. Legalábbis az a.r. design pattern-en belül.