R.A.D. sau Rapid Application Development este un numitor comun în ziua de azi atunci când vorbim despre metodologii de development. Pe scurt, această metodologie presupune adunarea de cerințe funcționale și non-funcționale prin workshop-uri sau metode de comunicare cât mai rapide, prototipizare și reutilizabilitatea componentelor implementate. Pentru a îndeplini cu succes această metodologie în ceea ce privește timpul de dezvoltare al aplicațiilor, multe companii folosesc unelte pentru generare de cod. Conceptul de Vendor Lock-in este menit să atragă atenția asupra deciziilor tehnice vis-a-vis de ușurința cu care putem integra un generator de cod în tehnologia pe care o folosim dar și dificultatea cu care putem customiza sau chiar elimina anumite componente generate. Este o practică extrem de comună; așa face Oracle, așa face IBM, așa face Apple, pe scurt, așa fac toți.
Pentru a detalia acest concept am ales un studiu de caz: Spring Roo vs Liferay Service Builder. Amândouă sunt unelte pentru generare de cod, amândouă sunt compatibile cu Liferay. Din acest punct de vedere voi face un DAR (Decision Analysis and Resolution).
Pentru această analiză vor fi folosite următoarele criterii:
Beneficiază de un plugin de Eclipse simplu și intuitiv pentru a rula unealta. O alta variantă este folosirea Ant sau Maven pentru rulare. Ea vă oferă un xml pentru configurare care, vă va genera pentru fiecare entitate câte un domain model, layer de persistență și de servicii. Totodată el va genera automat și metode de CRUD și metode utilitare pentru găsirea de entități dupa proprietățile acestora. Aceasta acoperă majoritatea straturile necesare, mai puțin cel de prezentare. În schimb, oferă integrare cu servicii web JSON si SOAP.
PUBLIC "-//Liferay//DTD Service Builder 6.1.0//EN"
"http://www.liferay.com/dtd/liferay-service-builder_6_1_0.dtd">
Vlad Hosu
TSM
Atributul de package-path din tag-ul "service-bilder" este folosit pentru numele pachetului de bază al codului generat. Tag-ul "namespace" este folosit pentru denumirea tabelei în baza de date iar în cazul acesta va fi tsm_Articol. Atributele de "local-service" si "remote-service" de pe tag-ul "entity" sunt folosite pentru specificarea persistenței locale și respectiv, dacă doriți și generarea de servicii web JSON și SOAP. Specificarea tag-ului "finder" va genera API si Implementare pentru obținerea unei liste de Articole in funcție de câmpul "autor". Desigur se poate customiza mult mai mult.
Pentru a configura Spring Roo aveti nevoie de STS (un Eclipse pentru Spring), o altă variantă este să alegeți consola. Pentru consolă, va trebui sa definiti pentru fiecare task câte o comandă. Veți identifica multe taskuri repetitive care ar putea fi abstractizate. Din punctul meu de vedere configurarea nu este atât de vizuală, precum o diagrama sau un xml. Un aspect negativ este: la fiecare fișier .java generat, Roo mai adaugă și un fișier AspectJ, asta înseamnă de două ori mai multe fișiere, deci o mentenanță dificilă pentru customizarea anumitor componente. Un aspect foarte important este ca Roo poate genera si stratul de prezentare la domeniul definit. Un mare atu față de Liferay Service Builder.
Același exemplu, referitor la entiatea Articol se va putea genera cu Roo folosind urmatoarele comenzi și în plus vom avea stratul de web, test de integrare și Spring Security:
Precum exmplicam anterior, dacă veți avea mai multe entități va trebui să repetați pentru fiecare dintre ele pașii referitori la definirea acestora. Comanda "perform tests" este pentru a testa integrarea entității generate in proiect. Comanda "perform eclipse" este pentru configurarea workspace-ului. Dacă aveți STS, nu mai este nevoie de rularea acestei comenzi. Altfel ea sau trebuie rulată sau este necesară instalarea unui plugin adițional pentru mavenizarea proiectului.
Este important de menționat că acest atribut nu contează decât dacă veți avea nevoie să intrați in codul generat. Alfel, cel mai probabil sursele generate vor ajunge într-o librărie externă.
Dacă punem un Sonar (vezi http://www.sonarsource.org/) pe el vom găsi la fiecare metodă câte un Major cel puțin. Spre exemplu:
• Prinderea de throwable in excepții
} catch (Throwable t) {
• Castarea neverificată
AdditionalInformationClp oldCplModel =
(AdditionalInformationClp) oldModel;
Modul in care se generează o entitate, este destul de complex și nu este conceput decât pentru a face parte dintr-un API (asta pentru a avea capacitatea de a suporta bazele de date majore ca și MSSQL, PostgreSQL, MySQL șamd). Aici nu includem si layer-ul de srvicii, care mai adauga in API înca opt clase: (http://www.liferay.com/community/wiki/-/wiki/Main/Service+Builder)
Oferă un cod care respectă best-pratice-urile impuse de Oracle si Google(pe partea de front-end)
Totodată, în orice moment aveți ocazia de a scoate o metodă din starea de cod generat în cod customizat ceea ce aduce un beneficiu destul de puternic.
Beneficiază doar de o pagină de Wiki - documentație inexistentă. De altfel, veți putea găsi foarte multe informații legate de această unealta și pe forumuri. Liferay are o comunitate destul de mare și în creștere.
In cazul unui parteneriat cu Liferay beneficiați de tot suportul necesar pentru a folosi această unealtă.
Roo în schimb are parte de o documentație destul de bogată prin comparație. În ceea ce privește forumurile, comunitatea Roo este înca destul de restransă.
Trebuie rescris totul pentru a ajunge la un cod Java extensibil, utilizabil si ușor de întreținut dar având in vedere că Liferay generează API-ul detașat de implementare, oricând se poate scrie o altă implementare într-un alt plugin dar asta nu vă va ajuta niciodata la scoaterea codului generat. Pe scurt, Liferay Service Builder oferă un contract pentru servicii și pentru model iar asta este suficient în majoritatea cazurilor.
Unealta poate translata tot ce este în fișierele AspectJ în cod Java. Asta oferă un grad de extensibilitate ridicat.
Este important de menționat că aspectele de integrare pot să vă ofere o pierdere de timp mai mare decăt beneficiul generatorului de cod în sine. Pe scurt, pot apărea probleme de prototipizare.
Totodată integrarea cu Spring este un pic diferită, anume container-ul de Spring este în Liferay și injecția de bean-uri se face într-un mod diferit din plugin. Asta presupune că veți avea de făcut o configurare suplimentară la Spring Roo pentru a-l putea folosi.
In concluzie, puteți să considerați folosirea Service Builder-ului atunci când nu se consideră partea de Vendor Lock-out, Calitatea Codului sau Documentația; asta presupune că nu vă puneți problema schimbării tehnologiei pe parcusul proiectului și aveți suficiente conușstințe vis-a-vis de acest tool. Pe de altă parte, Spring Roo vă oferă o satisfacție mai mare in ceea ce privește calitatea codului sau documentația dar veți avea si un risc, în funcție de prototipizarea aplicației.
de Tudor Rad
de Radu Popescu
de Ovidiu Mățan