Űrlapgenerálás Metawidgettel

Posted by | · · · · · · | Szoftverfejlesztés | 1 hozzászólás a(z) Űrlapgenerálás Metawidgettel bejegyzéshez

Webes alkalmazásfejlesztőként az életünk tele van űrlapokkal. Sokszor előfordul, hogy az alkalmazás nem is több egy egyszerű adminisztrációs felületnél, amivel felhasználóbarát módon módosíthatjuk adatbázisunk tartalmát. Ilyenkor, ha összetettebb folyamatokat nem tartalmaz  az üzleti logikánk, a fejlesztő élete abból áll, hogy létrehozza az entitásokat, majd létrehoz hozzájuk felületeket. Ha tényleg nagyon egyszerű űrlapokról van szó, akkor utóbbi összesen annyit jelent, hogy megnézzük az entitásunk mezőit, és a típusuknak megfelelően kirakunk egy komponenst. Az emberben ilyen esetben előbb-utóbb óhatatlanul felmerül a kérdés, hogy nem lehetne-e automatizálni ezt a monoton munkát? Az évek során már többen úgy döntöttek, hogy erre a kérdésre létezik igenlő válasz. Ezek közé az emberek közé tartozik Richard Kennard is, aki válaszának a Metawidget nevet adta. Ebben a bejegyzésben ezt az eszközt veszem górcső alá.

Mi is az a metawidget?

A projekt saját magát Object / User Interface Mapping (OIM) eszközként definiálja, azaz meglévő objektumainkhoz felhasználói felületeket köt. Mindezt igyekszik úgy megoldani, hogy közben ne vezessen be új technológiákat, hanem alkalmazkodjon meglévő front-end és back-end architektúránkhoz is. A gyakorlatban ez azt jelenti, hogy igyekszik széleskörűen támogatni az információk kinyerésének lehetőségét. A generáláshoz szükséges adatokat képes JavaBeanekből, annotációkból, xml konfigurációs fájlokból, stb. megszerezni, majd ebből az általunk használt front-end frameworknek megfelelő widgetet létrehozni. Utóbbiból pedig elég sokhoz találunk beépített támogatást: többek között HTML5-höz, JavaScripthez, Java Server Faceshez, Swinghez, Vaadinhoz, Androidhoz, stb…

mw_overview

Hogyan működik?

A Metawidget használata viszonylag egyszerű: minden támogatott front-end frameworkhöz létezik egy nativ Metawidget implementáció (pl. SwingMetawidget, JavaScript Metawidget, AndroidMetawidget, stb.), amit felhasználói felületünk megfelelő részéhez hozzáadhatunk. Paraméterben megadjuk neki, hogy mi az az objektum, amihez űrlapot szeretnénk generálni, és már kész is, a munka többi részét már automatikusan végzi a beállítások alapján.

Felhasznált  metawidgetünk példányait külön-külön konfigurálhatjuk, de megadhatunk xml-ben írt konfigurációs fájlt is. Ahhoz, hogy megfelelően tudjuk konfigurálni a generálást, meg kell ismerkednünk a Metawidget űrlapgenerálásának folyamatával. Ez a folyamat 5, jól elkülöníthető szakaszra bomlik:

1. Inspector futása

Első lépésként az ún. Inspector fog futni. Ennek a komponensnek a feladata minden információ megszerzése a back-end architektúrából, amire a generálás során szükségünk lehet. Ilyen információk lehetnek pl. entitások vizsgálatakor a JavaBean propertyk típusai, BeanValidation annotációk, ORM információk (pl. Hibernate, JPA), speciális Metawidget annotációk. Ezeket a vizsgálatokat tipikusan szétbontjuk külön Inspectorokra, amiket egy ún. CompositeInspector fog össze, és futtat megadott sorrendben. Az Inspectorok a használt Metawidget típusától függetlenek, azaz ugyanazt az Inspectort használhatjuk például SwingMetawidgetnél és AndroidMetawidgetnél is.

2. InspectionResultProcessorok futása

Második lépésben az InspectionResultProcessorok futnak. Ezeknek a komponenseknek a feladata az Inspector által visszaadott információhalmaz utólagos módosítása. Erre jó példa a generált űrlapon megjelenő widgetek sorrendjének meghatározása. Az entitásban az @UiComesAfter annotáció használatával minden property tudja magáról, hogy melyik property után következik, de a tényleges sorrend csak akkor állapítható meg, amikor már minden propertyt megvizsgáltunk. Fontos megjegyezni, hogy az InspectionResultProcessorok paraméterben megkapják az őket hívó Metawidgetet is, ezért a használható processorok (ahogy az összes további lépés komponensei is) függnek a használt Metawidget típusától.

3. WidgetBuilder futása

Harmadik lépésben fut a WidgetBuilder. Ennek a komponensnek a feladata a megtalált információk alapján meghatározni a létrehozandó front-end widgetet. A létrehozott komponensen tipikusan csak nagyon kevés vagy semennyi beállítást nem eszközöl. Általában a widgetek készítését is több WidgetBuilderre bontjuk szét, ilyenkor ezek összefogására használhatjuk a CompositeWidgetBuildert. Ez sorban végighív minden megadott WidgetBuildert, amíg valamelyiktől komponenst nem kap.

4. WidgetProcessorok futása

Negyedik lépésként jönnek a WidgetProcessorok. Ezeknek a komponenseknek a felelőssége a WidgetBuilderek által generált komponensek megfelelő konfigurálása. Például ha az Inspector által összegyűjött információk alapján egy adott widget csak olvasható kell, hogy legyen, a megfelelő WidgetProcessor fogja ezt beállítani.
Fontos, hogy bár általában csak ennyire használjuk a WidgetProcessorokat, hatókörük ennél tovább terjed: ha egy adott WidgetProcessor úgy itéli meg, akár teljesen le is cserélheti a widgetet; ill. szükség esetén ki is törölheti, eltüntetve ezáltal a generált űrlapról az adott propertyt.

5. Layout futása

Ötödik lépésként végül a Layout fut. A név egy kicsit talán megtévesztő lehet: ez a Layout nem azonos a választott front-endünk natív layout komponenseivel. A Layout felelőssége, hogy megfelelő módon elrendezve elhelyezze a generált widgeteinket a választott front-end natív layoutjain, de ebbe beleérti például szükség esetén a widgetekhez tartozó címkék elhelyezését, az űrlap nevének elhelyezését, stb… Mivel ez a szakasz már erősen függ a választott front-endtől, a Layoutok konfigurálása elég különböző lehet.

mw_architecture

A Metawidget űrlapgenerálásának folyamata

Benyomások

Pár hónapja már használjuk a Metawidgetet, és ezalatt az idő alatt sikerült néhány erősségét és gyengeségét kiismerni. Először is ne gondolja senki, hogy a Metawidget kiváltja a programozót aztáltal, hogy “out-of-the-box” támogat sok front-endet. Ez a támogatás ugyanis nem azt jelenti, hogy rögtön annotációkból módosíthatjuk minden natív widget minden tulajdonságát. Pusztán lehetőséget teremt nekünk ennek megvalósítására. Nincs rögtön implementálva minden, amire vágyunk (nem is lehetne, hiszen minden cég, minden projekt mást kíván), inkább csak útmutatást kapunk, hogyan is tudjuk felhasználni a Metawidgetet az adott front-enddel. Talán az a legszemléletesebb megfogalmazás, ha azt mondom, hogy a Metawidget nem egy űrlapgenerátor, hanem egy keretrendszer űrlapgenerátor készítéséhez. És ebben  nagyon jó!

Használatával egy nagyon kényelmes, jól kezelhető keretet kapunk az űrlapgenerátor összeállításához. Az 5 lépésből álló munkafolyamat moduláris felépítésének köszönhetően a generálás eredménye könnyen konfigurálható, bővíthető. A bővítés egyszerű, könnyen párhuzamosítható folyamat, hiszen egymástól jól elhatárolt részekből áll. A dokumentációra nem lehet panaszunk, részletesen bemutat mindent. Ráadásul mivel a Metawidgetet eleve úgy tervezték, hogy mindenki könnyedén testreszabhassa, ezért minden lépéshez vannak származtatásra szánt alapértelmezett implementációk, melyek használata még egyszerűbbé teszi az életünket. Az is pozitívumként említhető, hogy ha űrlapjainkat nem kézzel hozzuk létre, hanem generáljuk, akkor a sok / minden űrlapot érintő módosítások gyorsan elvégezhetőek.

Szóval az élet szép, a madarak csicseregnek, mi pedig percek alatt végzünk minden űrlappal. Aztán egyszercsak szembe jön egy kósza igény, hogy jó lenne, ha “A” mező értéke csak akkor lenne szerkeszthető, ha “B” mező értéke ez és ez. És ettől a mondattól elhallgatnak a csicsergő madarak, mi pedig gondterhelt tekintettel böngésszük a kódot, hol is tudnánk a történetbe becsempészni a  függőségeket, hiszen valójában nincsenek a kezünkben ezek a mezők. Van egy Metawidgetünk, ami jótékonyan elfedi előlünk az összeset. Arra azért van lehetőségünk, hogy kézzel elkészítsünk egy mezőt, és megmondjuk neki, hogy adott helyen azt használja. Ez működőképes megoldás is lehet, ha van egy hosszú űrlapunk, amin összesen két mező között van függőség. Csak aztán hamarosan kiderül, hogy “C” mezőnek meg végülis “D”-től kellene függenie, ami persze függ “E”-től… és hamar ott tartunk, hogy minden mezőnket ismét kézzel írjuk.

Másik lehetőség, hogy elkérjük a Metawidgettől a mezőt, és azt használjuk fel. Ezzel például az a baj, hogy a Metawidgetnek nem kötelező erre lehetőséget biztosítania (ha jól tudom, nem is mindegyik Metawidget teszi), másrészt pedig amelyik biztosít rá lehetőséget, az sem feltétlenül megbízható (VaadinMetawidget például a Vaadin mezők egy általános célú mezőtulajdonságát használja fel ehhez, aminek az értékét például egy WidgetProcessorban mi is könnyedén módosíthatjuk). Ám még ha minden mellettünk áll is éppen, és megfelelő módon el tudjuk kérni a mezőt a Metawidgettől, akkor is szembesülnünk kell azzal a problémával, hogy sajnos nem tudjuk, mi is az a mező, ami a kezünkben van. Hiszen lehet, hogy ma csak egy sima szöveges mező, de holnap valaki átkonfigurálja a beállításokat, és máris mondjuk egy legördülő van nálunk. Szóval vagy nekiállunk mindenféle feltételezéseket alkotni a generált mezőinkről, vagy belátjuk, hogy ez nem a jó irány.

Eljátszhatunk még sok megoldási gondolatkísérlettel (például valamilyen eventbusos megoldást alkalmazva, ahol a mezőknek nem kell egymást ismerniük ahhoz, hogy egymás eseményeire reagáljanak), és még az is lehet, hogy találunk működő megoldást. Mi arra jutottunk, hogy ezek már annyira bonyolítják az űrlap generálását, hogy elveszítjük azt az előnyt, ami miatt egyáltalán használni akartuk a Metawidgetet, nevezetesen, hogy könnyen és gyorsan generáljuk az űrlapokat. Szóval bármennyire is nagyszerű eszköz a Metawidget, a dinamikus űrlapokba sajnos már beletörik a bicskája.

Azért mindezek ellenére meg kell jegyeznem, hogy bár nem képes dinamikus űrlapokat készíteni, ez nem jelenti, hogy egyáltalán nem használhatjuk fel ilyenhez. Jelenleg mi egy olyan megoldást alkalmazunk, amiben az űrlap generálásához használandó információkat teljes mértékben a Metawidgettel szerezzük meg. Ez a része ugyanis ez esetben is remekül használható: nem csak összegyűjti az információkat, de szabványos xml formátumban vissza is adja nekünk, így könnyedén hasznosíthatjuk bárhol.

Zárszó

Összefoglalva azt mondhatom, hogy ha a megfelelő helyzetben akarjuk használni, a Metawidget nagyon erős és hasznos eszközünk lehet. Nálunk az a tapasztalat, hogy az űrlapok nem elég statikusak ahhoz, hogy teljesen a Metawidgetre hagyatkozva tudjuk őket generálni, de ha valakinek sok, egyszerű űrlapot kell hamar felmutatnia, mindenképpen érdemes vetnie rá egy pillantást!


One Comment

Takács Ákos says:

2013. május 24. at 22:13

Nem igazán tudnék most hozzászólni a témához, de túl sok gyengébb vagy igénytelen írást olvastam és kommenteltem, kritizáltam a neten. Meg kell nyugtatnom magam, hogy nem csak negatív kritikát tudok. És jó látni, hogy nem csak olyan cikkek születnek.

Szóval igényesnek tűnnek az írásaitok.

Reply

Leave a comment to Takács Ákos

Cancel Reply