joi, decembrie 23, 2010

Manifest pentru Dezvoltarea de Software Agil

Traducerea mea pentru (Agile Manifesto)

Manifest pentru Dezvoltarea Agila de Soft

Noi facem cunoscute cai mai bune de a dezvolta soft practicand dezvoltarea si ajutand pe altii sa o faca. Prin aceasta munca noi am ajuns la urmatoarele valori:

  • Indivizi si interactiuni in defavoarea proceselor si uneltelor
  • Software care functioneaza in defavoarea documentatiilor atotcuprinzatoare
  • Colaborarea cu clientii in defavoarea negocierii contractelor
  • Raspuns la schimbare in defavoarea urmaririi unui plan

Chiar daca este valoare in partea dreapta a frazei, pentru noi partea stanga a frazei este mult mai valoroasa

Principiile din spatele manifestului

Noi urmam aceste principii:

  • Prioritatea nostra de baza este aceea de a satisface clientul prin livrarea de soft util cat mai devreme si in mod neintrerupt.
  • Schimbarile cerintelor sunt binevenite, chiar si tarziu in procesul de dezvoltare. Procesele Agile exlploateaza schimbarea in avantajul competitional al clientului.
  • Livrarea frecventa de soft functional, incepand de la cateva saptamani pana la cateva luni, cu preferinta la un interval de timp mai scurt.
  • Cei care cunosc domeniul aplicatiei si dezvoltarorii trebuie sa lucreze impreuna pe tot parcursul proiectul
  • Proiectele se construiesc in jurul indivizilor motivate
  • Ofera-le mediul de lucru si suportul de care au nevoie, si ai incredere ca-si vor face treaba.
  • Cea mai eficenta si efectiva metoda de a transmite informatiile spre si in inteirorul unei echipe de dezvoltare este conversatia fata catre fata.
  • Softul care functioneaza este principala unitate de masura pentru progres.
  • Procesele agile promoveaza dezvoltarea sustinuta.
  • Sponsorii, dezvoltatorii si utilizatorii trebuie sa fie capabili sa mentina un ritm constant pe o perioada nedefinita de timp.
  • Atentia continua la excelenta tehnica si un design bun dau valoare agilitatii.
  • Simplitatea--arta de a maximiza cantitatea de munca care nu e nevoie sa fie facuta--este esentiala.
  • Cele mai bune arhitecturi, cerinte, si cel mai bun design sunt generate din echipele care se organizeaza singure
  • La intervale regulate, echipele reflecteaza cum pot deveni eficiente, apoi isi inbunatatesc si isi ajusteaza corespunzator comportamentul.

joi, decembrie 16, 2010

LENOVO ThinkPad T410

In sfarsit aseara am pornit pentru prima oara laptopul mult visat Lenovo T410. Scorul obtinut este cel care urmeaza (este coborat in jos de placa grafica Intel Graphics Media Accelerator 5700MHD - AMT). Configuratia ThinkPad T410 laptop with Automatic Switchable Graphics ofererea si posibilitatea de a avea o placa grafica NVIDIA NVS 3100m Optimus Graphics 512MB DDR3 with AMT):

Configuratia este urmatoarea:
  • Genuine Windows 7 Professional 64 bit
  • Intel Core i5-560M @ 2.66GHz (3.2Ghz Turbo), 1066MHz system bus, 3MB L2 cache
  • Intel Hyper-threading Technology, Intel Turbo Boost Technology
  • 4GB PC3-8500 1066MHz DDR3
  • Intel Graphics Media Accelerator HD - AMT
  • 14.1" WXGA (1280 x 800) TFT w/ LED backlight
  • 2.0 Megapixel Camera
  • 320GB 7200rpm SATA HDD
  • Thinkpad 11 b/g/n WiFi
  • 5-in-1 card reader and modem (MMC, Memory Stick, Memory Stick Pro, SD, SDHC)
  • Ultranav (TrackPoint and Touchpad)
  • DVD Recordable 8x Max Dual Layer, Ultrabay Slim SATA
  • 6-cell Lithium Ion battery
  • Genuine Lenovo Warranty 1 Year Depot (International Warranty 2516)
Primele impresii (in mare tin de experienta avuta in trecut cu un T60):
  • Tastatura excelenta
  • Camera Web excelenta (chiar si cu putina lumina)
  • Mute si desablare sonor marcate prin led-uri
  • Windows 7 e ok (sunt dezorientat putin pentru ca de ani de zile lucrez cu Windows XP)
  • Start/stop pentru sistemul de operare e rapid dar nu foarte rapid
  • Pentru instalare sistemului este o partitie de disc speciala din care se pot crea disk-urile de boot (calculatorul a venit fara nici un CD/DVD)
  • Think Advantage si toate unelte Lenovo sunt updatate fata de T60 (mult mai clare)
  • Eranul e wide putin prea scund (am senzatia ca nu incape in inaltime prea multa informatie) - folosesc un monitor extern pentru a compensa asta
Am folosit ninite.com pentru a instala bulk mai multe soft-uri. Foarte ingenios!

marți, decembrie 07, 2010

JAPAN 2010



Ce m-a surprins in Japonia (fara a incerca sa compar cu Romania pentru ca nu se poate compara - sa zicem ca in matematica unde poti sa nu introduci o relatie de ordine intr-o multime pentru ca elementele nu se pot practic compara dupa nici un criteriu):

  • principala senzatie cu care am ramas este aceea de siguranta si neagresivitate; chair daca e posibil sa fie doar o salvare a aparentelor (cred ca interiorul lor este mai agitat decat pare) totusi in alte parti ale lumii se poate simti o senzatie de agresivitate care in Japonia nu exista
  • in trenurile lor rapide (Shinkansen) de fiecare data cand intra sau iese din vagon, controlorul sau persoana care vinde mancare saluta facand o plecaciune (chiar daca eram doar 2 prsoane in vagon); nu e intamplator, toti fac asta ca si cum ar fi in "job description"-ul lor
  • de cate ori am intrebat persoane de pe strada (nu erau functionari si nu aveau nici o obligatie in acest sens fata de noi) despre o locatie despre care nu stiam unde este si ne-a insotit 500 de metri pana a fost sigura ca am juns (ni s-a intamplat ca cineva sa fuga cu noi ca sa prindem trenul)
  • functionarii chiar daca nu stiu engleza (cei din gara de exemplu) fac orice sa-ti rezolve cazul
  • am avut supriza sa vad intr-o gara (deoarece conductorul nu stia engleza ne-a aratat un set de carduri in engleza cu datele fiecarui tren) un card pentru un tren pe care vroiam sa-l luam la unul din impegatii de miscare si am avut surpriza sa vad ca erau trecute nu doar minutele ci si secundele la care trebuia sa vina (ceva in genul 10:12:30); asa a si venit, la secunda
  • mancarea traditionala pare a fi foarte sanatoasa (in general fructe de mare) dar total nepotrivita pentru gusturile mele (am avut supriza ca pestele sa fie extrem de dulce - ca si cum l-ar fi facut cu zahar)
  • la intrarea in restaurantele traditionale (in care se mananca stand in genunchi pe jos) trebuie sa lasi incaltamintea la intrare (am avut supriza sa vad in Tokyo printre zgarie nori, incaltari lasate la intrarea in cladire - banui ca acolo ra un restaurant)
  • de cateva ori am fost intrebati de oameni in varsta de unde suntem - am avut surpriza ca una din persoane sa fi fost in Romaina - Transilvania/Brasov - avea o imresie foarte buna despre Romania
  • cafeau lor este foarte, foarte slaba (solutia a fost StarBuks care se gasesc cam peste tot in gari si metrou)
  • trenuri lor locale (si nu numai) opresc la un loc bine stabilit - locul unde o sa fie usile se stie in prealabil si este marcat; dimineata si nu numai ai supriza sa vezi cum oamenii stau in ordine pe 2 randuri la intrararile vagoaneleor, se dau la o parte sa iasa oamenii printre ei apoi se repliaza sa intre (e destul de inspaimantator sa vezi cum stau randuri, randuri asteptand trenul)
  • in trenurile locale (metrou) se motaie - foarte multi oameni par obositi, se folosesc telefoanele (jocuri dar oamnii nu vorbesc la telefon in public ci doar ptesupun ca dau mail sau SMS)
  • am vazut in suprmarket-uri oameni maturi care citesc reviste de benzi desionate - am crezut initial ca sunt pentru copii dar am inteles ca orice poate fi scris asa (de fapt in librarii jumatate din carti sunt in scrierea lor si jumatate cu benzi desenate - probabil se suprapune intr-u fel cu modul lor de a gandi si scrie in concepte)
  • sunt foarte multe automade de bauturi reci si calde: ceai, cafea, sucuri (unele ceaiuri sunt foarte bunel, cafeau ori slaba ori fara zahar)
  • toamna sunt peisaje deosebite in gradinile lor: artar Japonez (cu frunze mici si rosii - se pare ca solul lor e important pentru culoare), ginkgo biloba cu frunze galbene si fructe urat mirositoare, etc; gradini foarte frumoase cum nu am mai vazut

marți, septembrie 21, 2010

IBM Lenovo ThinkPad T60

Chiar daca sunt aproape total dedicat dezvoltarii de soft, trebuie sa recunosc ca in final tot la o masina fizica ajungem si deci este foarte important unde dezvoltam aplicatiile nostre (in fapt si masina pe care lucram influenteaza productivitatea noastra - pentru ca aplicatia Java ruleaza intr-o masina virtual care este instalata peste un sistem de operare care sta instalat in final pe o masina fizica). Incerc in acest post sa fac un review pentru cel mai bun calculator cu care am avut ocazia sa lucrez IBM(Lenovo) ThinkPad T60.

De-a lungul timplui am avut ocazia sa lucrez pe o multitudine de sisteme desktop/laptop atat acasa cat si la serviciu. Trebuie sa recunosc ca nimic nu m-a impresionat precum ultima masina pe care am avut-o in dotare: ThinkPad T60. Pe ea apareau atat siglele Lenovo cat si IBM – se pare ca dupa de IBM a externalizat partea de hardware spre Lenova le-a mai permis sa foloseasca logo-ul IBM pentru cativa ani (acum toate masinile mai noi din seria ThinkPad au doar sigla Lenovo). ThinkPad T60 este o masina pe care am simtit-o cu adevarat a indeplini majoritatea pretentiilor mele ca functionalitate si design in ceea ce fac in viata de zi cu zi – dezvoltarea de aplicatii. . Cred ca foarte greu m-ar putea convinge cinava ca un alt laptop este mai bun – pur si simplu am simtit ca este o masina foarte, foarte bine facuta.

Clasa T este clasa de laptopuri ThinkPad pentru categoria business – se poate simti asta din liniile drepte ale carcasei fara a pune la socoteala performantele interne ale masinii. Este foarte compact fara nici un fel de infloritura in partea de design - asa cum au din nefericire mai toate calculatoarele destinate utilizatorilor obisnuiti. T60 are o tastatura perfecta – de negasit la o alta masina, functioneaza fara sa produca zgomot aproape deloc, are o carcasa plata si cu linii drepte si fara inflexiuni la atingere si foarte rezistenta, baterie extinsa tine foarte mult, are balamale din otel care functioneaza impecabil – acestea sant cateva din caracteristicile externe ale masinii.

Referitor la performantele interne ale masinii – pare a fi facut pentru programare, multimedia sau orice implica procesare. Cateva dotari pe care le poate avea un T60. Procesor: Intel Mobile Core 2 Duo T5600 2x1.83GHz 2MB L2 cache 64biti. Eu am avut la dispozitie 3GB DDR2 PC6400 800MHz (permite 4M memorie). Perfomante la randare video prin placa video: ATi Mobility Radeon X1400 512MB vRam. Celerometer: hardul este monitorizat de un dispozitiv special - accelerometer - care, in functie de pozitia laptopului si de miscarile sesizate, opreste temporar hard disk-ul pentru a il proteja pe acesta (si implicit informatia de pe el) de eventualele socuri mecanice.

Uitandu-ma pe magazinul firmei producatoare am observant ca Lenovo promoveaza in present alte laptopuri din clasa T: T410 si T510. Nu stiu daca se mai pot achizitional T60/T61 noi - cele vechi (second hand) sunt pana in 500$ pe ebay.com si alte site-uri. Ce nu-mi place la T410 este hub-ul de 3 porturi USB care ii da un aspect neplacut pe latura stanga. La T510 nu-mi place restrangerea tastaturii pentru a face loc difuzoarelor in lateral (este mult mai pronuntata decat la T410). De asemenea in review-uri se pare ca sunt problem cu tastatuta la ambele modele – se produc inflexiuni ale carcasei la atingerea tastelor.

Ma voi referi la cateva aspecte exterioare (bune si mai putin bune) pe care le-am observat in ultimii doi ani la T60 (nu sunt neaparat cele mai importante dar pe mine m-au incantat/dezamagit):

Avantaje:
  • ThinkVantage – foarte usor de folosit in administrarea masinii – detectarea retelelor wireless e foarte intuitiva (accesss connection)
  • Butoanele multimedia foarte bine asezate si foarte intuitive
  • Fara zgomot la racire – caracteristica aceasta nu am mai intalnit-o la alte sisteme
  • ThinkLight – luminarea tastaturii pe timp de noapte
  • Se deschide perfect la 180 de grade
Dezavantaje:
  • touchpad and UltraNav buttons sunt putin prea jos si pot fi atinse din greseala daca nu lucrezi la masa
Lucruri interesante:
  • Water resistant – foarte interesant a fost un caz in care unul din colegii mei a varsat suc si si-a stricat tastatura (sucul nu e ca apa)
  • Luminozitate crescuta – am avut ocazia sa-l compare cu un T61 si surprinzator T61 nu permitea acelasi nivel de luminozitate (alti colegi aveau T61 in dotare)
Prezentare video:

miercuri, septembrie 15, 2010

Unelte utile

O lista de unelte care le consider utile (majoritatea sunt gratuite) in orice mediu de lucru - la final am pus cateva specifice programarii (in Java). Am sa incerc sa intretin lista in timp.

Acest post este un test - editarea lui s-a facut printr-un mai trimis la o adresa de email - o facilitate a blogger.com.


  • Eclipse
  • Hermes JMS
  • SoapUI
  • Navicat (MySQL)

--
Cristian Olaru
weblog: http://olaru.blogspot.com
mobile: 0743163039

marți, septembrie 14, 2010

Clean Code

Clean Code este o carte scrisa de Robert C. Martin - care incearca sa surprinda experienta lui in scrierea de cod, experienta care se intinde pe cateva decenii (in carte se remarca cum regulile s-au schimbat de-a lungul timpului odata cu evolutia limbajelor de programare). Am incercat sa citesc cartea (versiunea fizica) dar nu am avut timp decat pentru primele 5 capitole si sa le rasfoiesc pe celelate in una din saptamanile de vacanta din acest an - am remarcat cu ocazia asta cat de putin timp avem sa citim in mod clasic.

In aceasta carte totul este de bun simt si ne poate salva de cosmarul debugingului continuu - cateodata ma gandesc ca printre programatori sunt unuii (cei care fac mentenanta) care nu fac altceva decat sa caute in gunoaie (codul vechi). Din cate imi dau seama a aplica regulile din Clean Code impreuna cu TDD (Test Driven Development) reprezinta cea mai buna metoda de a creste calitetea interna a produselor software - a le face valoroase pe termen lung din perspectiva dezvoltarii ulterioare/mentenantei.

Clean code pleaca de la urmatoarea premiza: cu siguranta codul pe care il scriem astazi va fi citit de catre cineva (toti speram ca nu noi) in viitor. De acea claritatea lui este foarte importanta. A fi usor de citit implica si a fi usor de modificat. Daca dezvoltarea unui proiect dureaza pana intr-un an, metinera lui (mentenance) va dura mai multi ani. Aceasta implica fixare de bug-uri, adaugare de mici feature-uri etc, care implica interactiuni cu codul respectiv. Desigur se poate face orice in debugger unde se poate vedea absolut orice. Dar este mult mai complicat decat a lucra cu un cod clar care exprima de la sine pentru ce a fost scris - intr-un fel exprima businessul implementat.

Primul accent pus in carte este pe numele pe care le vom da claselor, metodelor, campurilor care compun aplicatiile noastre. Ele trebuie sa exprime de la sine scopul si contextul in care sunt folosite. Nu trebuie sa ne zgarcim cu lungimea pe care o va avea numele lor - cel mai important este ca ele sa fie cat se poate de expresive si clare. Codul trebuie schimbat si modificat pana indeplineste criteriile de calitate stabilite de noi - nu trebuie sa ne fie frica sa intervenim de oricate ori este nevoie (este o practica in metodologiile de agile de a partaja codul intre toti membrii echipei si a permite tuturor sa il modifice cu incredere)

Surprinzator sau nu in capitolul dedicat comentariilor suntem sfatuiti sa nu le folosim deloc - doar in anumite situatii. Idea de a pune un comentariu care sa dubleze codul comentat nu este o idee buna - la o urmatoare interventie asupra codului comentariul poate deveni desincronizat fata de cod. Acest lucru nu poate introduce decat confuzie - codul trebuie sa exprime de la sine ceea ce implementeaza. Pentru aceasta trebuie sa exprime intentia noastra in asa maniera incat comentariile sa fie de prisos.

Un aspet foarte important este modul in care scriem metodele (care dau functionalitatea claselor). Autorul ne propune metafora unui ziar (newspaper) in care stirile nu sunt prezentate toate in intregime pe prima pagina. Pe prima pagina ni se prezinta titlul si un rezumat urmand o trimitere la urmatoarea pagina unde este intreg continutul. Trebuie sa distingem astfel intre nivelurile de abstractizare dintr-o metoda si sa nu le amestecam. Asa vom avea pentru fiecare functonalitate implementata un arbore de metode care abstractizeaza pe niveluri diferite functionalitatea. Metodele care se refera la un acelari aspect de domeniu vor fi pastrate impreuna - intr-o aceasi unitate de compilare. Int-o metoda trebuie sa faca un singur lucru - daca vrem sa facem si altceva o putem face intr-o alta metoda pe care o vom apele.

Testele unitare/integrare trebuie sa ghideze dezvoltarea - in fapt codul pe care il scriem o sa fie mai ingrijit daca o sa facem teste pentru el pentru ca este dificil sa testam un cod complicat (e greu de exemplu sa introducem multe mock objects daca avem prea multe dependinte in metoda noastra, e greu sa facem prea multe assert-uri daca metoda noastra face mai multe lucruri). Testele trebuie sa fie punctul de executie pentru orice functionalitate nou pa care o introducem in aplicatie (nu trebuie sa rulam toata aplicatia pentru asta si sa folosim logging pentru a vedea ca ce am scris merge). Teoretic deployerea aplicatiei ar trebui sa o facem foarte rar, la final - dupa ce am dezvoltat local ghidati de teste unitare/integrare. De asemenea sugereaza sa folosim teste (unitare/integrare) si pentru a ne acomoda cu noile librarii pe care vrem sa le introducem in proiect.

Clean code este un coplement la idea de stil de codare sau cea de conventii de nume:

  • stil de codare - reprezinta un set consistent de reguli de sintaxa care trebuie respectate de intreaga echipa pentru coerenta codului. Se cunosc o serie de astfel de codari - Eclipse, Sun(Oracle), Apache; ele pot fi setate la nivel de IDE pentru a oferi coerenta in cod
  • conventii de nume - un set de cosistent de reguli pentru denumirile care se folosesc intr-o aplicatie pentru clase, metode, campuri - spre exemplu sufixarea anumitor categorii de clase (XyzService, XyzAction, XyzDAO)
In carte sunt enumerate si unele principii stiute de programare carora treuie sa le acordam atentia cuvenita: Open Closed Principle, Single Responsibility Principle si Law of Demeter.

marți, august 31, 2010

Multiple themes and skins

Este prima oara cand lucrez la o aplicatie Web care trebuie sa aiba mai multe look and feel-uri care pot fi schimbate in runtime (vom numi aceasta drept schimbarea temei aplicatie). Exista tehnologii web care permit schimbarea stilului (nu a a temei) in runtime – JSF, librarii de componente JS gen JQuery UI. Si in partea de clienti grei exista astfel de posibilitati: Swing LAF (o lista a lor), sau mai noul Eclipse RCP 4 – look and feel dat chiar prin CSS. Dar eu vreau sa schimb tot layout-ul aplicatiei cu toate resursele implicate – css, javascript, resurse gen imagini, bannere, etc.

Pentru mine definitiile pentru tema si skin arata mai mult in felul in care se definesc acestea in portlets (partal theme, portlet skin):
  • Tema – modificarile se produc la nivel de layout si stil (chiar daca stilul este dat de CSS si poate influenta foarte fin si layout-ul totusi o tema implica o schimbare dramatica a modului in care arata site-ul)
  • Skin – modificarile au loc la nivel de stil (a se vedea JQuery UI pentru exemplu)
Desigur notiunile de skin si theme sun folosite cu intelesuri diferite in tehnologii diferite. Un exemplu revelator pentru ce inseamna fiecare pentru mine este acest site cu teme pentru WordPress in care se poate face distinctia clara dintre cele doua. Intr-un fel tema poate fi modificata de catre administratorul site-ului deoarece implica modificari profunde in look and feel. Skin-ul poate fi modificat de user si pastrat de-a lungul sesiunii si dupa. Ambele schimbari trebuie sa se poata face in runtime – din panoul de administrare a aplicatiei.

Partea de prezentare pentru aplicatia in cauza este facuta cu Struts 2, Sitemesh (este valabil si pentru alt framework web gen Spring MVC sau alt layout framework gen Tiles). Deoarece tema implica modificari de layout in cazul temei concluzia la care am ajuns este: sa folosesc facilitatea asta de Struts 2 numita wildcards. Astfel applicationConfiguration* va pinta spre /WEB-INF/pages/admin/applicationConfiguration{1}.jsp.

In form o sa se foloseasca ceva de genul (theme va fi tinuta la nivel de applicatie – Application Context (Servlet context in servlets)): applicationConfiguration${theme}.html


Pentru fiecare tema se va crea un director in aplicatie sub un singur director parinte numit /themes. Structura unei teme ar arata ca aici cum e descrisa in Sitemesh.

  1. /decorators Directory containing all decorator files (e.g. main.jsp, printable.jsp).
  2. /includes Directory containing all files to be included into other files (e.g. header.jsp, footer.jsp, copyright.jsp).
  3. /images Directory containing all images (e.g. background.gif, logo.gif).
  4. /styles Directory containing all .CSS styles (e.g. ie4.css, ns4.css).
  5. /scripts Directory containing all scripts (JavaScript, VBScript files).

Vom avea cate un decorator de SiteMesh diferit pentru fiecare thema (care da layout-ul de baza pentru thema respectiva). Se refolosesc Action-urile de Struts pentru toate temele si in acest sens ele trebuie sa fie scrise o singura data si foarte bine definite - nu mai trebuie rescris nimic la nivelul lor in functie de tema - dar trebuie sa fie consistente pentru toate temele. Toate resursele grafice vor fi sub tema respectiva. Se vor duplica jsp-urile aplicatiei (se folosesc in fiecare resurse specifice temei) - dar pentru theme identice ca layout vor fi asemanatoare si deci se poate presupune ca vor putea fi refolosite.

Deci implementarea este dependenta de Struts 2 si de Sitemesh adica de tehnologiile folosite in aplicatie. Intrebarea este daca exista ceva mai generic (poate independent de framework-uri) sau mai bun. Din ce imi dau seama nu – doar la nivel de stil prin introducerea de CSS-uri diferite – care pot sa contina si mici chestiuni de layout dar nu diferente mari. Sunt curios cum s-ar putea face acest lucru la nivel de JSF – probabil entry point-ul ar fi la nivel de Facelets.

Anumite greutati in introducerea temelor multiple pentru o aplicatie apar in rescrierea de URL-uri (UrlRewrite), caching de pagini (OSCache) si securitate (ACEGI). O problema este introducerea unor variabile la nivel de aplicatie (numele temei, locatia temei in FileSystem) care trebuie folosite si repetate peste tot la nivel de JSP-uri.

duminică, iulie 25, 2010

De vara

Bicicleta de care nu m-am despartit niciodata in calartoriile cu masina din acesta vara(cred ca ar incapea doua in portbagaj daca m-as stradui putin). Ceva probleme doar in unele parcuri din Bucuresti unde biciclistii nu sunt foarte doriti. Pliabila, usoara si destul de scumpa.

vineri, iulie 16, 2010

Domain Driven Design

Sunt 3 posibile patternuri care ofera metode de a modela domeniul aplicatiei (Domain Logic Patterns) pe care Martin Fowler le prezinta in cartea sa Patterns of Enterprise Application Architecture (P of EAA). Nu intamplator el pleaca de la domeniu in enumerarea patternutilor enterprise – practic domeniul trebuie sa reprezinte inima aplicatiei si acolo trebuie sa fie amplasat businessul aplicatiei – practic cea mai importanta parte a aplicatiei. Ele sunt dupa cum urmeaza:
  • Transaction Script – domeniul este alcatuit din 2-3 grupari de clase – Services (numite de unii si Managers) care ascunde logica aplicatiei si DAO care ascunde persistenta (eventual facuta cu ORM); eventual un set additional de clase de Business care ofera calculabilitate
  • Table Module – bazat pe RowSet modificabil – mapare componenta la tabela – specific .NET
  • Domain Model – un domeniu bogat de obiecte care implementeaza efectiv business-ul aplicatiei si reprezinta cu adevarat inima aplicatiei

Cazul cel mai intalnit in J(2)EE este Transaction Script – se gasesc foarte multe aplicatii scrises in acest fel – aproape toate. Interfata face apeluri intr-un layer de servicii la nivelul carora se deschid tranzactii spre serverul de baze de date sau cozi de mesaje, etc. Business-ul se afla de obicei in servicii (care apeleaza clase DAO pentru persistenta) sau se mai creaza un pachet de obiecte BO care sa faca calculabilitate. Sunt foarte multe startere si exemple pe aceasta tema. Startere: Play, Roo, SpringFuse, Appfuse, (some MDA generators – Andromda, M2Spring, Sculptor) etc

Table Module se intalneste mai ales in cazul in care interfata e component based gen Swing (desktop) sau chiar JSF (Web – dar nu request/response based). Cazul in care o componenta infasoara un ResultSet care infasoara la randul lui o tabela in baza de date. ResultSet-ul este un cursor spre tabala care permite modificarea ei in runtime – daca este UPDATABLE. Si astfel de exemple se pot gasi – in general IDE-urile permit crearea de astfel de aplicatii prin drag and drop: Matisse in NetBeans (pentru Swing), JDeveloper (pentru ADF), etc. Sincer eu am experimentat acest pattern din primele zile ca dezvoltator folosind JBuilder – care avea un foarte bun system de dezvoltare pentru Swing – in care aduceai cu drag and drop componenta in fereastra. Structurile tabelare (grid) se pretau la a comunica cu o componenta nevizuala care infasura o tabela in baza de date (continea un cursor updatabil spre BD).

Cel mai rar intalnit pattern pentru a capta domeniul aplicatiei – sincer nu am avut niciodata sansa sa vad pana anul acesta o astfel de aplicatie - este Domain Model. Aici problema s-ar pune cam asa: intai construiesti un domeniu pentru aplicatia ta (un rich domain in sensul ca obiectele nu contin doar stare ci si functionalitate modeland in totalitate businessul abordat) apoi te gandesti cum ii asiguri o infrasctructura – adica aspectele tehnice vin la urma: persistenta, concurenta, securitate, tranzactionalitate, de ce nu si prezentare, etc. Nu e vorba doar de un domeniu sarac alcatuit spre exemplu prin maperi spre tabelele din baza de date – care sunt clase doar cu stare si fara functionalitati – asa cum se intampla in Transaction Script de obicei (o favoare pe care o ofera ORM-urile). Este vorba de un model complet pentru business testabil cu un framework de testare, neavand o parte de prezentare – eventual se poate folosi in faza initiala de dezvoltare o intefata de tip consola.

Teoretic (din perspective tehnologiilor existente pe piata), acesta a fost visul pentru EJB – de a feri dezvoltatorul de aspecte de infrastructura si a-l lasa se se concentreze pe business – dar tot ce s-a putut reusi cu EJB a fost sa se expuna un layer de servicii. Deci EJB-ul mai ales cum era initial cu Service Locator si fara Dependency Injection era parca facut pentru Transaction Script. Fara persistenta obiectuala cu ORM-uri (entity bean-urile initiale au fost un esec si deci initial se scria SQL native) si fara dependency injection (se punea mai mult problema pe a expune un serviciu pe care il localizai in runtime) cam greu sa te gandesti la altceva decat Transaction Script. Spring, Hibernate si mai nou EJB 3 (CDI + JPA) care le imita ofera un teren mai placut pentru o abordare a aplicatiilor la nivel tehnologic cu un domeniu bogat.

Domain Driven Design ofera o altfel de alternative dezvoltarii de aplicatii – care seamana oarecum cu ceea ce am invatat in facultate despre modelarea obiectuala dar nu coincide deloc cu ce am gasit in industrie dupa (a nu se intelege ca cred in academic). Ideea de a construe un model obiectual pentru businessul pe care il rezolvam. Aceasta problema ar fi fara iesire daca Eric Evans nu ar oferi in cartea lui o serie de patternuri pentru construirea unui astfel de domeniu – si chiar o arhitectura standard pentru o astfel de aplicatiei – si chiar o schita pentru un process de dezvoltare care impreuna diminueaza complexitatea unei astfel de abordari. Arhirtectura oferita este tot una stratificata (layered architecture) dar acomodata cu un domeniu bogat care trebuie creat initial si o infrastructura pentru el care vine ulterior.

Chiar daca pentru mine inca aceasta abordare reprezinta doar o curiozitate – sunt infectat cu stilul de programare actual din industrie bazat pe Transaction Script – trebuie sa recunosc dezavantajele abordarii curente. Surprinzator, este foarte dificila mentenanta – pentru ca logica este intradevar raspandita peste tot in aplicatie – de la prezentare pana in baza de date. Poate nu mententa in sine – pentru ca structura stratificata usureaza mentenanta. Dar cel mai sigur Transaction Script ingreuneaza intelegerea businesului abordat – direct din cod. Pentru ca, dezvoltator de Java (= total obiectual) fiind ar trebui sa fie foarte natural sa inteleg un model – care modeleaza o realitate decat un cod care este conceput sa transporte date din interfata spre baza de date si invers si amesteca businessul peste tot (ca sa nu mai spunem ca tendinta e de a-l duplica).

Pe site-un DDD exista o aplicatie demo care poate fi folosita drept model. Este unul dintre cele mai bune lucruri care se puteau face pentru a promova DDD. In fapt este prima aplicatie scrisa in acest fel pe care am gasit-o si care pentru oricine vrea sa implementeze DDD poate fi un punct de start. Foloseste framework-uri moderne pentru infrastructura (+ build). Foloseste pattern-urile din cartea lui Erik Evens. Este conform arhitecturii din carte. Procesul de dezvoltare nu este ilustrat – putem doar presupune ca s-a pornit prima oara cu un model.

Cred ca reprezinta o greseala sa abordam problema DDD partial, plecand de la un Transaction Script modificat, doar introducand diverse grupari de obiecte care par a imbogati businessul aplicatiei. O abordare radicala in modul de dezvoltare trebuie folosita pentru a face intradevar DDD. Pentru ca acum usecase-urile din cerintele utilizator se bazeaza pe descrierea interfetei si interactiunea utilizatorului cu interfata – deci accentual cade pe interfata = pornim de la interfata in dezvoltarea aplicatiei. Altii modeleaza mai intai baza de date – care releva intradevar entitatile aplicatiei - dar nu inima ei – in fapt abordeaza o simpla problema de infrastructura = persistenta. Dar ce ar fi sa pornim cu ceea ce e intradevar important – inima aplicatiei si sa o modelam obiectual. Oare suntem in stare sa facem un salt atat de mare in gandirea noastra?

PS: De curand am achizitionat cartea lui Eric Evans numita Domain-Driven Design: Tackling Complexity in the Heart of Software si acest articol este o censecinta a acestui lucru.

luni, mai 03, 2010

Pluginabilitate in aplicatiile web | JavaRomania

Introducere

Unul din lucrurile interesante pe care le-am observat in timp este pluginabilitatea aplicatiilor. Aceasta inseamna adaugarea de functionalitati noi in mod dinamic in runtime prin activarea/incarcarea unor pluginuri. Este cazul multor soft-uri deja consacrate dintre care cel mai cunoscut pentru dezvoltatorii de Java este Eclipse. Eclipse este in sine un conglomerat de plugin-uri care de la o versine la alta se bazeaza pe OSGi. Un alt exeplu pentru dezvoltatrii de Java este Hudson: http://wiki.hudson-ci.org/display/HUDSON/Plugin+tutorial.
In cazul aplicatiilor Web facute in Java exista deja cateva exemple de pluginabilitate. Unul din ele ar fi Jira si in general produdsele de la Atlassian care se bucura de asa ceva (a se vedea aici informatii despre sistemul lor de plugin-uri: http://confluence.atlassian.com/display/DEVNET/How+to+Build+an+Atlassian+Plugin). Aplicatiile din portofoliul companiei Atlassian permit crearea de plugin-uri de catre terte persoane prin care se imbogatesc functionalitatile aplicatiilor de baza.
In Java solutia clasica pentru pluginabilitate este OSGi (www.osgi.org) care reprezinta un standardul incontestabil pe acest domeniu. OSGi permite crearea de bundle-uri (care sunt de fapt jar-uri cu un manifest bine definit) care reprezinta plugin-urile care se pot instala in mod dinamic. In mod dinamic in runtime se rezolva dependentele bundle-ului de alte bundle-uri si de asemenea poate inregistra dinamic servicii intr-un registru de servicii.

Cazul meu

Eu sunt interesat in pluginabilitate la nivel de interfata Web pentru o aplicatie deja scrisa. In sensul ca vreau ca prin activare/deactivare de pluginuri sa apara/dispara functionalitati din interfata Web (mai specific fragmente din meniul lateral al aplicatiei care cuprind diverse statistici despre articolele publicate).
In acest sens am nevoie de o consola de administrare a pluginurilor:
Spre exemplu prin activarea pluginului Balaur va aparea urmatorul (ultimului) fragment in menu:

Resurse

Exista mai multe implementari de OSGi: Equinox, Felix,
Pentru a integra integra pluginabilitate in aplicatia mea am folosit Equinox drept implementare de OSGi embedat in aplicatia mea deja facuta (aplicatia de baza poarta numele de HOST application). Am ales Equinox deoarece pune la dispozitie un bridge - un servlet care este ridicat in runtime din host application si toate call-urile (HTTP requests) peste path-ul servit de acest servlet sunt redirectate spre servletii/JSP-urile din bundleurile OSGi. O aplicatie web exemplu pentru cum se embedeaza Equinox intr-un container de servlets se gaseste aici: http://www.eclipse.org/equinox/server/http_in_container.php.
Deci trebuie remarcat faptul ca sub bundle-urile de Equinox se pot inregistra servlet-uri si JSP-uri ca sub o aplicatie web obisnuita - declararea lor se face programatic dar se poate si declarativ folosind extensii intr-un fisier plugin.xml. De asemenea exista suport de JSTL + el. Prezint o lista a bundle-urilor necesare de pe equinox.org:
.
  • org.eclipse.equinox.servletbridge.http
    Hooks back into the servlet bridge and proxies requests through to the servlet container to provide an OSGi Http Service.
  • org.eclipse.equinox.http.servlet
    Provides the HttpServiceServlet used by http.servletbridge that when initialized registers an OSGi Http Service.
  • [optional] org.eclipse.equinox.http.registry
    Provides servlet, resource, and httpcontext extension points based on an OSGi HttpService
  • org.eclipse.equinox.servletbridge
    Launches the framework and provides a place for the framework to hook back into the servlet container.
JSP suport:
  • org.eclipse.equinox.jsp.jasper (Bundle)
    Provides an OSGi friendly JSPServlet based on the use of the Jasper 2 compiler and runtime.
  • org.eclipse.equinox.jsp.jasper.registry (Bundle)
    Provides a JSPFactory that allows JSP usage with the org.eclipse.equinox.http.registry.servlets extension-point

Lista completa a plugin-urilor incluzand si cele 2 plugin-uri custom este aceasta:

Ca o curiozitate am instalat si un plugin de Felix care este o consola web pentru gestionarea pluginurilor din container - in mod surprinzator chiar daca este un bundle de Felix si nu de Equinox a mers din prima incercare. Consola de administrare o puteti vedea aici:

Dezvoltare plugin-uri

Desigur pentru a testa sistemul am creat 2 plugin-uri custom folosind Eclipse IDE. Un articol interesant despre cum se dezvolta plugin-uri de OSGi este aici: http://www.vogella.de/articles/OSGi/article.html. Eclipse are o perspectiva aparte pentru dezvoltarea de plugin-uri (in principiu plugin-uri de Eclipse care au definite niste extensii peste OSGi). Se pot folosi drept model exemplele de pe equinox.org. Cele 2 plugin-uri construide mine sunt:

Primul plugin (com.integrationpath.mengine.console) este folosit pentru a afisa in host application lista de plugin-uri existente in aplicatie (/com.integrationpath.mengine.console/web/consoleAsync.jsp), status-ul lor si posibilitatea de activare/deactivare. De asemenea expune informatii (/com.integrationpath.mengine.console/web/plugins.jsp) despre plugin-urile active si locatia unde expun ele fragmentul ce trebuie integrat in meniu (via JSON). In host application in meniul lateral (sidebar) se vor agrega toate aceste fragmente folossind JQuery.

Integrare

Cea mai mare provocare este incampatibilitatea intre OSGi si oricare server de aplicatii existent. Cea mai buna idee e sa rescrii aplicatia conform OSGi dar in cazul meu aplicatia host este deja scrisa si deployata ca war intr-un container de servlets. Containerul OSGi care este embedat in aplicatia host este startat de aceasta si ruleaza in acelasi JVM, dar definitiile claselor sunt gestionate de classloade-re diferite (lucrurile sunt si mai complexe pentru ca la nivel de fiecare bundle exista un class loader separat prin modul de constructie OSGi). Desigur se pune problema comunicarii intre HOST application si bundle-urile din containerul OSGi (de fapt in ambele sensuri) deoarece bundle-urile trebuie sa prezinte functionaitati care au treaba cu buisinessul aplicatiei de baza.
Prima incercare a fost de a exporta pachetele de Spring dispre host app spre OSGi si a accesa web application contex-ul de Spring din host application sub OSGi. Fara success. O ultima solutie a ramas expunerea functionalitatilor din host application ca Web Service (am preferat JSON) si consumarea lor in bundle-urile de OSGi.

luni, martie 22, 2010

Optimizarea performantei unei aplicatii Web

Descriu in continuare o serie de unelte (biblioteci Java si tool-uri) folosite in optimizarea performantei pentru o aplicatie Web. Aplicatia are un spatiu limitat de memorie pentru a rula (< 64 M); dupa cateva zile aplicatia cade - Out of memory; aplicatia se incarca greu in browser.


Posibile probleme

1. problema: entitatile sunt folosite si in prezentare si sunt incarcate cu date; solutia: de folosit fetching in mapari - lazy loading pentru colectii in general

In mod implicit prin generare, maparile JPA contin lazy la nivelul colectiilor

2. problema: pe sesiune se pun inutil obiecte; solutie: sa se foloseasca scopul potrivit; daca sunt pe sesiune deja nu se mai pun

La nivel de session ma intreb mai intai daca sub atributul dat exista ceva (!=null); daca da nu fac nimic, daca nu pun valoare sub atribut

Unelte folosite

Glassbox - evidentierea problemelor din runtime

Un tool util in urmarirea aplicatiei in runtime si determinarea punctelor ei slabe in ceea ce priveste performanta. Se instalaeaza in acelasi app server cu aplicatia care se vrea testata si ofera o consola in care sunt logate problemele de performanta care apar. Ofera sugestii pentru rezolvarea lor - destul de utile. Este o aplicatie utila care evidentiaza corect problemele dar nu poate inlocui un profiler.

YSlow - optimizarea paginilor Web

O unealta care concretizeaza experienta acumulata de Yahoo in optimizarea paginilor web. Este un plugin de Firefox care sta alaturi de FireBug si arata ce bune practici sunt incalcate in paginile aplicatiei tale. In general recomandarile sunt: sa se minimizeze numarul de call-uri HTTP prin concatenarea de resurse: javascript, css, introducerea unor atribute in headerul HTTP pentru a se face cache la nivel de proxy, etc. Ofera chiar tool-uri care te pot ajuta in fixarea acestor proble. A fosst nevoie si deun filtro pentru a modifica Expire date pentru resursele statice.

JProfiler - profiling

Cel mai bun profiler pe care il stiu - cei care l-au creat au fost foarte inspirati. Arata in mod dinamic memoria HEAP, thread-urile, call-urile de metode si timpul lor de executie, thread-urile, etc. O unealta foarte utila in a vedea ce se intampla in codul aplicatiei tale in runtime. Evidentiaza clasele specifica de J2EE, permite introduerea de filtre doar pe clasele care ne intereseaza (face introspectie pe cele care ne intereseaza).

WAPT - load test tool

Inlocuitor pentru JMeter - loat test tool. Permite inregistrarea unui script care sa fie executat ulterior pe mai multe thread-uri. Poate simula in acest caz mai mullti useri care folosesc aplicatia furnizand astfel datele necesare pentru profiler. Am preferat WAPT in defavoare JMeter pentru usurinta in folosire - JMeter e mai usor de folosit programatic pentru nightly test, etc (inregistrarea scripturilor se face prin activarea unui proxy). WAPT poate fi folosit cu 20 useri pe o periaoda scurta de timp.

OSCache - cache in partea de prezentare

OScache permite cacahe pentru pagini (filtru) sau fragmente (librarie de taguri). Cache-ul se face dupa chei diferite care pot fi incluse in grupuri. Se paote face flush programatic pe keie, pattern de chei, grupuri sau la intreg cache-ul. Stocarea se poate face in file sistem sau in memori. Configurarea intr-un fisier de configurare - filtrul direct in web.xml.

Am preferat cache pe pagini - pagina principala in care sunt aratate toate articolele si cele in care se arata continutul articolelor. Au aparut probleme cu partea de securitate a aplicatiei si cu URL rewrite. Trebuie avut in vedere ca partea de administrare (aflata sub un user autentificat) nu trebuie sa intre in cache - un user nelogat poate vedea o pagina cu informatii disponibila doar userilor autentificati. O buna practica este selectarea foarte clara a paginilor care pot fi introduse in cache. Invalidarea cache-ului se face programatic la nivel de action in momentul in care se adauga un articol sau comentariu. Efectele sunt vizibile cu ochiul liber.

Folosirea de cache la nivel de fragmente de pagini este nefolositoare - as economisi doar timpul necesar randarii tag-urilor JSTL, deoarece call-ul spre /servici/DAO se face din action, care doar redirecteaza spre JSP. La nivel de pagini, cache-ul pot evita call-urile spre baza date in totalite (pana la invalidarea lui).

EHCache - cache la nivel de Hibernate

EHcache este folosit implicit de Hibernate ca cache de level 1 la nivel de Hibernate session. Pentru level 2 la nivel de session factory este nevoie de a configura explicit clasele care se vor cache-ui. Si in acest caz am preferat cache in file system. De asemenea cache-ul la niivel de query-uri trebuie configurat explicit pentru a fi creat. Pentru a verifica procesul de cache trebuie activat loggerul de ehcache. Configurarea de ehcache se face la nivel de fisier de configurare - numit implicit ehcache.xml.

Compass - index pentru search

Index la nivel de Hibernate - prin intermediul lui se indexeaza toate obiectele care sunt persistate (salvate/incarcate) in baza de date, oferind posibilitatea de a raspunde rapid la search-urile din aplicatie fara a mai face query-uri la nivel de baza de date. Clasele care se doresc indexate trebuie marcate (am ales fisiere de configurare pentrua nu introduce adnotari in entitati - prefer sa le generez pe cele de Hibernate de fiecare data cand schimb ceva in tabele). Indexul poate fi regenerat oricand programatic - si se reactualizeaza singur in runtime prin integrarea cu Hibernate. In spate foloseste Lucene pentru indexare - deci se vor face query-uri de tip Lucene pentru regasirea informatiilor.

Log4J

Pentru a verifica functionarea librariilor de cache, Log4J a fost activat si setat pe un nivel corestunzator. De asemenea am preferat sa fac cache in file sistem pentru a urmari efectiv cache-ul.

Alte unelte utile

Eclipse - debug - pentru a verifica daca se fac call-uri in layerele aplicatiei - thread-ul ramane blocat in breackpoint.
Firebug - analiza paginilor web - DOM, trafic, etc
WireShark - analiza traficului de retea - la un nivel foarte detaliat in tot stack-ul TCP-IP
Tomcat - un enviroment destinat numai testarii; in dezvoltare se foloseste Jetty

Solutii finale

- folosire de cache-uri la nivel de prezentare si de persitenta
- optimizarea incarcarii paginilor web generate

Pasi urmatori

Un increase de memorie si mutarea cache-urilor in memory
Optimizare riguroasa la nivelul query-urilor de Hibernate
Pooling - verificarea parametrilor pentru thread pool in app server si connection pool pentru baza de date
Eliminarea servlet filter nefolositi sau maparea lor pe url-uri mai stricte
Eliminarea librariilor inutile din classpath - pentru a evita Permsize exception
Scalabilitate - Teracotta, SpringS tc server

luni, martie 08, 2010

Interviu despre Java şi educaţie

Un fragment dintr-un interviu acordat pentru lec-academy.ro.

LEC Academy este un proiect Line Education Center care are ca scop sa va aduca zilnic cate un tutorial video sau scris despre Java, PHP, Microsoft Office, dar si articole cu noutati din industria IT. Prezentam un fragment, restul interviului il puteti urmari lec-academy.ro


Ce sfaturi ai pentru cineva care ştie elementele de baza în programare şi vrea să “se apuce” de java?

Să înceapă să foloseasca limbajul Java în viaţa de zi cu zi în dezvoltarea de aplicaţii efective, începând de la API-ul standard dat de JSE şi continuând cu bibliotecile şi framework-urile enterprise. Să citeasca puţin şi să scrie mai mult cod. O bună idee este să disece o aplicaţie deja făcută în Java chiar dacă este imperfectă şi să înveţe din experienţa altora. Să se implice atât în partea de dezvoltare de aplicaţii pentru desktop cât şi în partea de Web pentru a-şi lărgi domeniul de experienţă. Să se acomodeze cu tool-urile specifice limbajului: IDE-uri, unelte de build, servere de aplicaţii, etc. Să nu se limiteze doar la cunoaşterea teoretică!

Care este, în opinia ta, diferenţa dintre un developer bun şi unul mediocru?

Consider că un adevărat dezvoltator, pe care eu îl numesc “pur sange” este cel care şi-a făcut o profesie (meserie) din programare. În sensul că nu este ataşat doar de un job sau o firma sau un proiect ci de limbaj, tehnologii, şi programare în general, cele din urmă având un scop şi o durată de viaţă mult mai mare decât primele. Desigur, e imposibil să ştii totul. Părerea mea este că ideea de “cache levels” este aplicabilă şi în afara programării. Întotdeauna avem un set de informaţii foarte des folosite pe care le ţinem în memorie la îndemână, dar ne vine uşor să căutăm dupa alte informaţii mai rar folosite pe Web, în cărţi, etc. Dar în general un bun programator are o înţelegere mai profundă a limbajului şi a tehnologiilor venită din pasiunea pentru programare deoarece este afectiv legat de acestea şi drept consecinţă acumulează mai uşor cunoştinţe.

Ce sfaturi ai avea pentru cineva care este începător în “ale programării” indiferent de limbajul folosit? Cum ajungi un developer bun?

Sunt un susţinător al experienţei (şi oarecum împotriva sistemului academic) pe care o consider singura care poate să dea un folos efectiv învăţării. Teoria foarte rar are o aplicabilitate practică imediata mai ales dacă este adusă la un grad înalt de formalizare aşa cum se întâmplă în facultate. Consider ca anii consumaţi în facultate aproape inutil trebuie să fie răscumpăraţi prin ani de munca în producţie folosind efectiv tehnologii, unelte, etc.


Source: http://lec-academy.ro