tsm_5_2012_ro

56
TO DAY SOFTWARE No. 5 / 2012 www.todaysoftmag.ro MAGAZINE Propriul start-up Tehnici SEO interne - partea I Google Guice Agile & Testing & Mobile - trei concepte convergente Cum sa crești o mentalitate agilă în contextul dezvoltării software? Joacă „Hard Choices” în fiecare sprint și rascumpără-ți datoriile! Designul experienței utilizatorului și moduri de aplicare în dezvoltarea produsului Construirea interfețelor web dinamice folosind MVVM și ASP.NET UseTogether. Ce? Cum? şi De ce? Planificator Ecologic pentru OpenNebula Social networks Core Data – În spatele scenei 5 practici Java pe care le folosesc Microsoft Kinect - Ghid de programare Testarea ca știință exactă Noutăți în Windows Communication Foundation 4.5 Service Bus Topics din Windows Azure Design-ul aplicaţiilor Android pentru toate platformele Malware pe Android statistici, comportament, identificare și neutralizare Gogu

Upload: today-software-magazine

Post on 06-Mar-2016

229 views

Category:

Documents


6 download

DESCRIPTION

http://www.todaysoftmag.com/pdf/TSM_5_2012_ro.pdf

TRANSCRIPT

TSM T O D A YS O F T WA R E

No. 5 / 2012 • www.todaysoftmag.ro

M AG A Z I N E

Propriul start-up

Tehnici SEO interne - partea I

Google Guice

Agile & Testing & Mobile - trei concepte convergente

Cum sa crești o mentalitate agilă în contextul dezvoltării software?

Joacă „Hard Choices” în fiecare sprint și rascumpără-ți datoriile!

Designul experienței utilizatorului și moduri de aplicare în dezvoltarea produsului

Construirea interfețelor web dinamice folosind MVVM și ASP.NET

UseTogether. Ce? Cum? şi De ce?

Planificator Ecologic pentru OpenNebula

Social networks

Core Data – În spatele scenei

5 practici Java pe care le folosesc

Microsoft Kinect - Ghid de programare

Testarea ca știință exactă

Noutăți în Windows Communication Foundation 4.5

Service Bus Topics din Windows Azure

Design-ul aplicaţiilor Android pentru toate platformele

Malware pe Android statistici, comportament, identificare și neutralizare

Gogu

6Propriul start-up

Călin Biriș

10UseTogether. Ce? Cum? şi

De ce? Echipa UseTogether

10Tehnici SEO

interneRadu Popescu

13Google Guice

Mădălin Ilie

16Agile & Testing & Mobile -

3 concepte convergenteRares Irimies

20Design-ul aplicaţiilor

Android pentru toate platformele

Claudia Dumitraș

23Cum sa cresti o mentalitate agila in contextul dezvoltarii

software?Andrei Chirilă

26Joacă „Hard Choices” în

fiecare sprint si rascumpără-ti datoriile!

Adrian Lupei

26Planificator Ecologic pentru

OpenNebula Ionut Anghel si Tudor Cioara

31Designul experientei

utilizatorului si moduri de aplicare în dezvoltarea

produsuluiSveatoslav Vizitiu

34Construirea interfetelor web dinamice folosind MVVM si ASP.NETCsaba Porkoláb

36Social networksAndreea Pârvu

38Core Data –În spatele sceneiZoltán, Pap-Dávid

415 practici Java pe care le folosescTavi Bolog

44Microsoft Kinect - Ghid de programareEchipa Simplex

46Testarea ca stiintă exactăAndrei Contan

47Noutăti în Windows CommunicationFoundation 4.5Leonard Abu-Saa

49Service Bus Topics din WindowsAzureRadu Vunvulea

52Malware pe Android - statistici, comportament, identificare si neutralizareAndrei Avădănei

54GoguSimona Bonghez

4 nr. 5/2012 | www.todaysoftmag.ro

Editorial

Zilele acestea Apple a lansat iPhone 5, iar această informație probabile că este mai populară decât un campionat de fotbal întreg. Nu voi lua în considerare dacă partea de hardware este mai interesantă decât a concurenței, cert este că sunt ase-

mănătoare, iar factorul major de diferențiere va fi sistemul de operare și diversitatea din App Store. Din acest punct de vedere iOS 6 a schimbat un pic regulile generale ale jocu-lui prin introducerea suportului de hărți proprii, prin renunțarea la aplicatia YouTube, printr-o mai bună integrare cu rețelele sociale și o îmbunătățire a sincronizării datelor între device-uri aproape în timp real. Paradoxal, aceasta îl aproprie mai mult de strate-gia celor de la Microsoft unde vedem cam același lucru: sistemul propriu de hărți prin Nokia folosind Navteq, o foarte bună integrare a rețelelor sociale în OS și suportul de sincronizare. Android continuă trend-ul de disruptive business, prin oferirea sa gratuită, dar multitudinea de device-uri care pot fi suportate face uneori destul de provocatoare dezvoltarea de aplicații. În funcție de device experiența utilizatorului variază mult. Dacă acum zece ani, tot ceea ce conta era platforma hardware și implicit producătorul dispozi-tivului cum ar fi Nokia sau Sony Erricson în zilele noastre luăm in considerare mai mult ceea ce oferă sistemul de operare în sine. Ecosistemul la care se primește acces devine mai valoros decât hardware-ul achiziționat. Din toate acestea, un dezvoltator de software ar trebui să înțeleagă că un singur produs poate avea un succes pe term scurt și că pe termen lung contează crearea acelui ecosistem care conține o experiență cât mai com-pletă a utilizatorilor pentru domeniul țintă. Pentru programatori lecția s-ar traduce prin punerea accentului pe diversitate și pe preocuparea de a înțelege toate nivelele unui astfel de ecosistem, de a se implica activ în dezvoltarea sa începând cu aplicația ce rulează pe device și terminând cu backend-ul. Numărul curent al revistei contine cu 40% mai multe articole decât în numărul precedent și poate fi considerat o expresie a acestei diversități. Accentul pus pe metodologia Agile și multitudinea de articole care pornesc de la definirea layout-ului aplicației pe dispozitivele Android, tehnici de optimizare SEO, Goolge Guice, Core Data iOS, best practice-uri Java, noutăți WCF 4.5, Service Bus din Windows Azure, design-ul experienței utilizatorului, statistici și comportament al virușilor Android și multe altele pe care le puteți găsi în paginile revistei oferă cititorilor o gamă variată de subiecte.

Importanța ecosistemului poate fi extinsă și la nivel local iar aici revista TSM sprijnă comunitatea pentru o mai bună comunicare și împărtășire a experienței tehnice a progra-matorilor și nu numai. Implicarea mediului academic pentru o colaborare cu firmele de IT din Cluj și accentuarea importantanței research-ului va fi dezbătută într-un eveniment special, vom reveni cu detalii. Colaborarea cu cercetătorii locali poate fi de asemenea un prilej bun de pornire a unor startup-uri locale care s-ar dovedi astfel cu adevărat inovatoare.

Închei prin a mulțumi tuturor colaboratorilor, sponsorilor revistei și nu în ultimul rând vouă cititorilor.

Mulţumesc,

Ovidiu Măţan

Fondator și CEO Today Software Magazine

Ovidiu Măţan, [email protected]

Fondator și CEO Today Software Magazine

editorial

5www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

Redacţie

Fondator / Editor in chief: Ovidiu Mățan [email protected]

Editor (startups și interviuri): Marius Mornea [email protected]

Graphic designer: Dan Hădărău [email protected]

Colaborator marketing: Ioana Fane [email protected]

Reviewer: Romulus Pașca [email protected]

Reviewer: Tavi Bolog [email protected]

Produs de Today Software Solutions SRL

str. Plopilor, nr. 75/77Cluj-Napoca, Cluj, [email protected]

www.todaysoftmag.rowww.facebook.com/todaysoftmag

twitter.com/todaysoftmag

ISSN 2284 – 6352

Copyright Today Software Magazine

Reproducerea parțială sau totală a articolelordin revista Today Software Magazine

fără acordul redacției este strict interzisă.

www.todaysoftmag.rowww.todaysoftmag.com

Mădălin [email protected]

Cluj Java Discipline Lead@ Endava

Leonard [email protected]

System Architect@ Arobs

Radu [email protected]

QA și Web designer @ Small Footprint

Rareș Irimieș[email protected]

Senior QA @ 3Pillar Global Romania

Călin Biriș [email protected]

Călin Biriș este Crocodilul de Marketing la Trilulilu și Președinte al IAA Young Professionals Cluj.

Tavi [email protected]

Development lead @Nokia

Adrian [email protected]

Project Manager și Software Engineering Manager @ Bitdefender

Echipa [email protected]

Sveatoslav [email protected]

User Experience and User interface Senior Designer

Andreea Pâ[email protected]

Recruiter în cadrul Endava și trainer specializat în dezvoltarea abilităților si competenețelor de leadership

Radu [email protected]

Senior Software Engineer@iQuest

Zoltán, Pap-Dá[email protected]

Software Engineer @ Macadamian

Simona Bonghez, [email protected]

Speaker, trainer și consultant în managementul proiectelor,

Owner al Confucius Consulting

Andrei Chirilă [email protected]

Team LeaderTechnical Architect@ ISDC

Ionuț Anghel, Ph. [email protected]

Asistent Doctor Inginer Departamentul CalculatoareFacultatea de Automatica si Calculatoare

Andrei Conț[email protected]

Principle QA @ Betfair Co-Founder Romanian Testing Community

Lista autorilor

Andrei Avădă[email protected]

Fondator si CEO DefCampCEO worldit.info

Tudor Cioară, Ph. [email protected]

Asistent Doctor Inginer Departamentul CalculatoareFacultatea de Automatica si Calculatoare

Claudia Dumitraș[email protected]

Android Developer @ Skobbler

6 nr. 5/2012 | www.todaysoftmag.ro

Propriul startup

Am auzit că piața din Cluj se va schimba. Salariile din domeniu cresc și au ajuns la un nivel mare, comparabil cu nive-lul salariilor din țările vestice. Companiile de outsourcing vor începe să sufere din acest motiv iar clienții lor vor începe să își îndrepte proiectele către alte piețe mai ieftine.

O direcție sănătoasă pentru orice com-panie locală de outsourcing ar fi să înceapă să construiască produse proprii care să se adreseze la mai multe piețe de clienți. Astfel, difersificând portofoliul, nu vor ține toate ouăle în același coș iar riscurile vor fi împărțite.

Dar de ce să aștepți după compania în care lucrezi să te pună într-o echipă pe un produs nou, când poți chiar tu să pornești un start-up în afara orelor de birou și să lucrezi și pentru tine?

Avantajul tău în acest moment este că lucrezi pe un salar bun și că în timpul liber te poți concentra pe proiecte proprii de viitor.

Dacă te gândești la un start-up lucrurile

cele mai importante pe care ar trebui să le iei în considerare: echipa, banii și ideea.

EchipaCea mai importantă resursă într-un

start-up este cea de capital uman, adică specialiștii. Mulți care se gândesc să por-nească un start-up cad în capcana banilor, crezând că fără bani de investiție nu pot realiza un produs de succes pe piață și din acest motiv nu se mai apucă de nimic. Eu cred că dacă vei reuși să faci o echipă bună, care să livreze un produs de valoare, cu un model de business sănătos, banii vor veni.

Problema echipei este că aceasta trebuie să fie formată din membri cu aptitudini complementare. Când a pornit Trilulilu, proiectul a avut o echipă inițială formată din buni specialiști în design, programare, administrare de server, management, bran-ding și legal. O mână de oameni care s-au completat unii pe ceilalți și care au lucrat pentru același scop de a lansa pe piață un serviciu de impact.

Gândește-te la competențele de care vei

Gândește-te la trei branduri locale de online, care au pornit din Cluj și au ajuns să aibă succes la nivel național sau internațional. Nu-i așa că este greu să le găsești? Deși, dacă te gândești la principalele centre IT din România, Clujul este

în primele trei. Avem mulți practicieni în IT, dar care sunt absorbiți de companiile de outsourcing. Prea puține sunt companiile care si-au dezvoltat produse proprii.

startups management

Călin Biriș[email protected]

Călin Biriș este Crocodilul de Marketing la Trilulilu și Președinte al IAA Young Professionals Cluj. Pasionat fiind de mediul online și de marketing, a ţinut zeci de prezentări despre publicitate online și marketing, atât pentru studenţi cât și pentru mediul de business. Este o persoană activă în mediul online pe blogul personal www.calinbiris.ro și pe reţelele sociale.

7www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

avea nevoie în start-up-ul tău și găsește cei mai buni oameni care să se implice alături de tine.

BaniiDacă ai pornit un start-up care crezi

că are potențial, este mai ușor decât te-ai aștepta să ajungi la persoane dispuse să îți ofere feedback sau chiar să investească în ideea echipei tale.

Am scris recent pe blogul propriu des-pre evenimentele dedicate start-up-urilor, unde se întâlnesc învestitorii de tip Angel cu echipe care au nevoie de bani pentru un produs pe care îl dezvoltă. Sunt deja o mână de astfel de evenimente care se întâmplă anual.

Însă nu toți investitorii doresc să pro-moveze că au bani de dat. Am aflat și de persoane care au bani puși deoparte și care așteaptă echipa potrivită în care să inves-tească, chiar dacă nu participă la astfel de evenimente.

De asemenea, te poți gândi și la alte surse de finanțare precum împrumuturile bancare, fondurile nerambursabile sau cei 3F – friends, family and fools.

Însă mai important decât ”cum vei face rost de investiție pentru start-up” este să te gândești care va fi modelul de business pe care îl vei urma și cum vei face bani. Dacă ai un răspuns bun la asta, investiția va veni

odată cu creșterea numărului de clienți plătitori.

IdeeaAm avut mai multe ocazii să stau de

vorbă cu dezvoltatori care doreau să se implice în proiecte proprii, dar care nu aveau o idee în care să creadă că va avea succes pe piață. Pe lângă acest lucru, din cauza inerției de a lucra pentru proiectele altor clienți, nu aveau timpul să se gân-dească la propiectele proprii. Cel mai bun lucru care ar putea să îl facă este să încerce să găsească idei prin networking.

Participând la mai multe competiții de start-up-uri am realizat că cele mai bune idei vin de la oameni care poate nu sunt atât de orientați către partea de IT ci mai mult către partea de business. Poate din acest motiv ar trebui organizate tot mai multe întâlniri între specialiști din busi-ness cu specialiști în IT, care să încerce să găsească acele idei de start-up care ar avea șanse de reușită.

Dacă nu ai o idee de start-up, încearcă să te întâlnești tot mai mult cu oameni din domenii diferite de al tău și descoperă oportunități pe care le-au văzut în diferite piețe. Poate împreună veți găsi soluții care ar putea avea succes.

Dar cum îți dai seama că o idee este bună?

Cel mai ușor mod de a testa o idee este să încerci să vinzi produsul înainte să îl realizezi efectiv. S-ar putea să găsești clienți dispuși să plătească acum pentru o soluție pe care să o livrezi doar peste un anumit timp. Din același test vei putea descoperi nevoi la care nici nu te-ai gândit inițial că vor putea fi acoperite de serviciul sau pro-dusul tău.

Dar totuși de ce să începi să lucrezi la un start-up și să nu te mulțumești cu ce ai acum?

Pentru că ai posibilitatea:• Să lucrezi la propriile idei,• Să câștigi mai bine,• Să fii mai apreciat pentru ceea ce

creezi,• Să cunoști mai mulți oameni și să

călătorești mai mult,• Să nu ai toate ouăle în același coș, în

caz că se întâmplă ceva.

Degeaba Clujul este în topul centrelor IT din țară, dacă nu ne putem lăuda cu propriile realizări. Depinde numai de tine să încerci ceva nou, să faci o echipă și să începi ceva, orice. Ai mai multe de câștigat decât de pierdut. Gândește-te.

management

8 nr. 5/2012 | www.todaysoftmag.ro

UseTogether. Ce? Cum? şi De ce?

Totul a început în urmă cu aproximativ șase luni la Startup Weekend Cluj, unde, doisprezece persoane care se întâlneau atunci pentru prima dată au hotărât să își unească forţele în jurul unei idei simple dar puternice: de ce să cumperi când poţi împrumuta? Planul părea destul de simplu: trebuia să punem cap la cap cele mai bune idei pe care le aveam și să construim

un proof of concept pentru o platformă online dedicată schimbului de obiecte.

startups

Din fericire, întreaga experienţă a fost una mai mult decât pozitivă. Am plecat de acolo cu sfaturi, idei și perspective noi și, poate cel mai important, am primit validarea conceptului de la care a pornit proiectul.

Au urmat o mulţime de ședinţe, pla-nuri, schiţe și mâzgălituri și, lucrând în timpul rămas liber dintre locul de muncă, facultate, familie, prieteni și tot felul de alte îndatoriri, astăzi putem spune cu bucurie că UseTogether.ro se află în final în beta și merge (sperăm) pe drumul cel bun.

Acest articol va descrie aventurile developmentului din cadrul UseTogether precum și suita de tehnologii pe care lucrăm și care ne fac viaţa mai ușoară. Deși am câștigat Startup Weekend Cluj cu o arhi-tectură clasică PHP, MySQL și JavaScript, am ajuns destul de rapid la concluzia că aveam nevoie de ceva mai puternic si mai flexibil dacă aveam de gând să oferim ideii de UseTogether o implementare pe măsură. După lungi discuții asupra tehnologiilor pe care urma să le folosim, ne-am oprit în cele din urmă asupra framework-ului Django ca piatră de temelie pentru proiect. Django e un framework web MVC scris în Python care pune accent pe development rapid și design simplu și pragmatic.

Apărut în jurul anului 2005 din frus-trarea autorilor săi de a întreține site-uri complexe scrise în PHP, Django și-a înce-put viața ca un layer de abstractizare între codul Python propriu zis și mod_python. Deși intenția nu a fost de a crea un fra-mework web, sătui să mai copieze cod de la un proiect la altul, autorii au reușit să abstractizeze și să dezvolte layer-ul inițial suficient de mult încât experiența de a lucra în Django să devină una mai mult decât plăcută.

Totuși de ce Django și nu, spre exem-plu, Ruby on Rails? Pentru noi, motivația a fost destul de simplă: toți patru lucrasem deja mai mult sau mai puțin în Python și, în plus, Django a fost numit după un chita-rist și anume - Django Reinhardt. Ca idee,

printre site-urile populare implementate în Django se numără Pinterest, Instagram, Mozilla, The Washington Times și Public Broadcasting Service.

Problema cu tehnologiile fiind rezol-vată, mai aveam nevoie doar de un sistem de project management și issue tracking. Ne-am decis inițial să folosim Trac. După cum e descris și pe http://trac.edgewall.org/, Trac e un sistem minimalist ce com-bină un wiki și un issue tracker. E ideal pentru proiectele în cadrul cărora se știe ce e de făcut și comunicarea față în față se produce ușor și frecvent. Din păcate, noi nu îndeplineam nici măcar una din-tre condițiile de mai sus. Nu aveam o idee perfect închegată vizavi de modul în care vom aborda proiectul și fiind și angajați / studenți, reușeam să ne întâlnim toți patru mai mult în weekend-uri.

Așa că ne-am reorientat spre ceva mai complex, care să ne permită să fim mai bine conectați la întregul proces de deve-lopment. Din fericire, cei de la Facebook au avut probleme similare cu mult înain-tea noastră și, ca răspuns la ele, s-a născut Phabricator. Phabricator este o suită de aplicații web menite să facă viața devilor mai ușoară și deși seamănă destul de mult cu sisteme precum Trac sau Redmine, o scurtă vizită pe http://phabricator.org/ va dezvălui că acesta din urmă se ia ceva mai puțin în serios: Facebook engineers rave about Phabricator, describing it with glowing terms like „okay” and „manda-tory”. De la descrieri precum “Shows code so you can look at it”, până la Close a ticket “out of spite” sau butonul de Submit care a fost redenumit în “Clowncopterize” (beca-use clowns and helicopters are awesome), Phabricator este ca o lungă plimbare prin Nerdtown, pe Geek street. Un tool scris de programatori pentru programatori.

Dincolo de interfața hazlie, foarte ase-mănătoare cu Facebook, Phabricator îți oferă tot ce ți-ai putea dori de la un sis-tem de project management modern: code review, issue tracking, source browsing,

wiki, CLI precum și un API. Ca sisteme de versionare, Phabricator poate lucra cu Git, Subversion și Mercurial și poate fi rulat de pe Linux, Mac și chiar Windows.

Pentru noi, code review-urile s-au dovedit a fi o adevărată mană cerească. Dacă atunci când ai de scris cod ești dis-pus să te înduri de propria-ți persoană și să renunți la calitatea codului în favoarea soluțiilor quick and dirty, din fericire, noi oamenii suntem destul de neiertători cu cei din jurul nostru. Și dacă de cele mai multe ori nu ești dispus să vezi bârna din propriul ochi, vă asigur că până și cele mai mici paie din ochiul celuilalt au fost scoase la iveală în modul ăsta. Nu pot să subliniez îndea-juns importanța code review-urilor într-un proiect ca UseTogether, cu o echipă mică de devi, în care oricare dintre membri trebuie să fie în stare să înțeleagă și să modifice orice parte din cod.

Și nu în ultimul rând, trusa noastră de tool-uri a fost completată de Git. De ce Git? Pentru că e distribuit, foarte ușor de folosit și foarte rapid.

Pe final, vă urăm cât mai puține bug-uri critice și vă lăsăm cu o fărâmă de înțelepciune: “Python is a drop-in replace-ment for BASIC in the sense that Optimus Prime is a drop-in replacement for a truck.” - Cory Dodt.

Echipa UseTogether

De la stanga la dreapta, pe randul de sus:Daniel Rusu, Mircea Vădan, Alex Țiff, Cătălin Pintea, Gabi Nagy, Paul Călin, Adriana Valendorfean, Victor Miron; iar pe randul de jos:Larisa Anghel, Ioana Hrițcu, Sorina Andreșan, Alina Borbely

9www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

Transylvania Java User GroupComunitate dedicată tehnologiilor Java.Website: http://www.transylvania-jug.org/Data înfiinţării: 15.05.2008 / Nr. Membri: 493 / Nr. Evenimente: 38

Romanian Testing CommunityComunitate dedicată QA.Website: http://www.romaniatesting.roData înfiinţării: 10.05.2011 / Nr. Membri: 520 / Nr. Evenimente: 1

Cluj.rbComunitate dedicată tehnologiilor Ruby.Website: http://www.meetup.com/cluj-rb/Data înfiinţării: 25.08.2010 / Nr. Membri: 112 / Nr. Evenimente: 27

The Cluj Napoca Agile Software Meetup GroupComunitate dedicată metodelor Agile de dezvoltare software.Website: http://www.agileworks.roData înfiinţării: 04.10.2010 / Nr. Membri: 234 / Nr. Evenimente: 13

Cluj Semantic WEB MeetupComunitate dedicată tehnologiilor semantice.Website: http://www.meetup.com/Cluj-Semantic-WEB/Data înfiinţării: 08.05.2010 / Nr. Membri: 125 / Nr. Evenimente: 18

Romanian Association for Better SoftwareComunitate dedicata oamenilor cu experienta din IT indiferent de tehnologie sau specializare.Website: http://www.rabs.roData înfiinţării: 10.02.2011 / Nr. Membri: 173 / Nr. Evenimente: 9

Google Technology User Group Cluj-NapocaComunitate dedicată tehnologiilor Google.Website: http://cluj-napoca.gtug.ro/Data înfiinţării: 10.12.2011 / Nr. Membri: 25 / Nr. Evenimente: 7

Cluj Mobile DevelopersComunitate dedicată tehnologiilor mobile.Website: http://www.meetup.com/Cluj-Mobile-Developers/Data înfiinţării: 08.05.2011 / Nr. Membri: 45 / Nr. Evenimente: 2

Secţiunea comunitate își propune să ţină evidenţa grupurilor de profesioniști relevante pentru industria IT, dar și un calendar de evenimente și întâlniri din acest sector. Pentru început prezentăm principalele iniţiative din mediul local, în timp intenţionând să creștem acest index până ce va conţine toate comunităţile locale, dar și cele naţionale cu prezenţă și activitate pe plan local.

Criteriul ales pentru ordonare este în funcţie de numărul de membri și de activitatea grupurilor (evenimente locale) raportate la durata lor de viață astfel sperăm să obţinem o ierarhie a gradul de implicare, al organizatorilor și al membrilor.

Calendar

Septembrie 25Technical Days C++C ont a c t : ht tp : / / b l o g . p e opl e - c e nt r i c . ro / ne w s /un-nou-eveniment-technical-days-c-la-cluj

Septembrie 26Open Coffee Meetup - #HaSH - Hack a Server HackathonContact: http://www.facebook.com/opencoffeecluj/events

Septembrie 29Windows 8 Dev CampContact: http://codecamp-cluj-sept2012.eventbrite.com

Octombrie 2Patterns for Parallel ProgrammingContact: http://www.rabs.ro

Octombrie 17 HTML5 and Problem solving in Web DesignContact: http://www.meetup.com/Cluj-Semantic-WEB

Noiembrie 9 Artificial Intelligence, Computational Game Theory, and Decision Theory - Unifying pathsContact: [email protected]

Comunităţi IT Cluj-Napoca

10 nr. 5/2012 | www.todaysoftmag.ro

Tehnici SEO interne partea I

programare

Meta tagsRolul tagului <title> este identic cu

al tagului <meta description>, adică de a crește rata de click în pagina de rezul-tate. Folosirea unor titluri interesante sau cuvinte cheie în interiorul tagului, pe cât posibil în primele cuvinte, va crește această rată de click. În cazul în care se dorește folo-sirea unui nume de brand în tagul <title> avem parte de două abordări diferite. Dacă brandul e unul cunoscut, este recoman-dat ca acesta să se regăsească aproape de începutul tagului (exemplu: Nume Brand | Nume Pagina). În cazul brandurilor mici sau noi, trebuie să adăugăm numele bran-dului spre finalul tagului (exemplu: Nume Pagina | Nume Brand). Aceste abordări pornesc de la ideea că numele unui brand important are un impact foarte puternic în decizia de a da click pe respectivul rezultat, pe când un brand necunoscut nu va atrage clickuri. Lungimea tagului <title> trebuie să fie în intervalul 10-64 caractere, astfel că trebuie evitate cuvintele fără valoare descriptivă, care doar ocupă spaţiul, pre-cum “de”, “pe”, “în”, “pentru” etc.

Există un mit legat de <Meta

Keyword>, și anume că trebuie să avem cât mai multe cuvinte cheie într-o pagină, acestea fiind importante în SERPS. Nimic mai fals. Încă din septembrie 2009, Matt Cutts (care ocupa la vremea respectivă poziţia de Search Quality Manager) anunţa, pe unul din blogurile Google, că celebrul motor de căutare nu va mai ţine cont de <Meta Keywords>. Adăugarea și folosirea acestui tag nu este dăunatoare, dar totuși ne răpește din timpul necesar altor sarcini, având în vedere că tagul nu este folosit.

Încă un mit ar fi acela că <meta descrip-tion> ar ajuta la apariţia unei pagini cât mai sus în rezultatele Google. De fapt, rolul acestui meta tag este acela de a convinge cât mai multe persoane să dea click pe rezul-tatul nostru. <Meta description> este o unealtă care ajută foarte mult în creșterea ratei de click în SERPS. Toate persoanele care văd o pagină cu rezultate (în urma unei căutari Google) vor trebui să decidă pe care din linkurile afișate vor intra. Descrierea care oferă un sumar foarte bun sau interesant al conţinutului va determina majoritatea oamenilor să dea click pe linkul respectiv. O abordare mai controversată în

Radu [email protected]

QA și Web designer @ Small Footprint

Dacă în numărul precedent am putut vedea care au fost cele mai importante modificări ale algoritmilor de căutare ai Google, în acest număr am decis să realizăm un articol în care să prezentăm unele dintre cele importante tehnici

de optimizare pentru motoarele de căutare, aplicabile zonei de SEO intern. Aceste teh-nici, deși ușor de aplicat, oferă rezultate foarte bune pe termen lung, în privinţa creșterii traficului organic. În cele ce urmează vă propunem spre informare aceste câteva tehnici.

11www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

cazul acestui meta tag este folosirea unor descrieri foarte interesante, dar incomplete (terminate în mijlocul unei idei cu trei puncte de suspensie). Aceasta va face ca persoana care e pusă în faţa respectivului rezultat să dorească foarte mult să afle mai multe detalii despre descriere, astfel încât va da click. Legat de lungimea descrierii, trebuie menţionat că aceasta ar trebui să fie între 50-150 de caractere, pentru cele mai bune rezultate.

Fişierul Sitemap.xml şi rolul săuSitemap-ul este un fișier de tip XML,

care ajută motoarele de căutare să găsească mai ușor paginile pe care le va indexa, ofe-rind o listă care conţine toate URL-urile site-ului. Acest fișier a fost folosit pentru prima dată de către Google în 2005, iar în 2006 motoarele de căutare MSN și Yahoo au anunţat că vor utiliza și ele sitemap-ul pentru indexare. Formatul fișierului Sitemap.xml este unul foarte simplu, ast-fel încât oricine îl poate crea. Există totuși generatoare online gratuite care pot face acest lucru într-un timp mult mai scurt. Dintre acestea, cel mai bun și rapid este www.xml-sitemaps.com. În cazul în care acest fișier va conţine peste 50.000 de URL-uri sau va avea o dimensiune mai mare de 10 Mb, trebuie comprimat în format gzip.

<?xml version=”1.0” encoding=”utf-8”?><urlset xmlns=”http://www.sitemaps.org/schemas/ sitemap/0.9”>

<url>

<!-- această secţiune se va repeta pentru fiecare pagină în parte --> <loc>http://example.com/</loc> <!-- adresa paginii --> <lastmod>2006-11-18</lastmod> <!--data ultimei modificări a conţinutului -->

<changefreq>daily</changefreq> <!--intervalul de schimbare al conţinutului-->

<priority>0.8</priority> <!-- prioritatea paginii (poate varia de la 0.0 pana la 1.0) --> </url></urlset>

Odată creat, fișierul Sitemap.xml va trebui adăugat în directorul de bază al situ-lui (root), fiind accesibil prin adresa www.exemplu.ro/sitemap.xml.

Validarea codului HTML şi importanţa saUn lucru de foarte multe ori uitat sau

dat la o parte din cauza timpului redus de dezvoltare este validarea codului HTML. Ne amintim cu toţii de vremurile în care pe majoritatea site-urilor erau prezente, în zona inferioară, etichete sau mici logo-uri pe care scria că acel site conţine cod HTML

și CSS valid. De fapt, ele nu erau doar un motiv de laudă, ci ajutau în principiu la SEO. Motoarele de căutare trebuie să par-seze codul HTML, pentru a găsi conţinutul. În momentul în care există anumite erori, este posibil ca unele părţi din site să nu poată fi luate în considerare, astfel că toată munca de optimizare a conţinutului va fi în zadar.

Printre cele mai comune erori de vali-dare HTML amintim următoarele:• Închiderea unor taguri. Tagul <div>

se va închide prin </div>, în timp ce tagul <img> se va închide într-un singur format <img />

• Folosirea unui DOCTYPE incorect

• Lipsa artibutului ALT din interiorul tagului pentru imagini

• Imbricarea incorectă a tagurilor. Iată un mod greșit de imbricare <div><b>TEXT</div></b>. Modul corect este: <div><b>TEXT</b></div>

• Convertirea caracterelor speciale în simboluri de tip Entity. În cazul caracterului “©” în codul HTML vom folosi “&copy;”

Verificarea validităţii codului HTML se poate realiza folosind unealta gratuită pusă la dispoziţia oricui pe site-ul www.valida-tor.w3.org. Deși nu toate erorile HTML pot

12 nr. 5/2012 | www.todaysoftmag.ro

avea consecinţe asupra SEO, este recoman-dat să avem un cod valid și curat, măcar din considerente legate de profesionalism și calitate.

<Bold> vs. <strong> şi <i> vs. <em>Trebuie să întelegem că motoarele

de căutare, în momentul în care se uită la o pagina web, nu văd același lucru ca o persoană reală. Ele văd codul sursă și îl analizează. Din această cauză, deși pentru noi un text cuprins în tagul <b> (bold) arată la fel ca un text cuprins în tagul <strong>, motoarele de căutare văd două lucruri total diferite. Tagul <b> este per-ceput ca un tag de design, oferind un stil mai pronunţat cuvintelor asupra cărora este folosit, pe când tagul <strong> oferă o informaţie semantică, prin care se eviden-ţiază conţinutul. În general, tagul <em> va fi folosit pentru conţinutul generat de către utilizatori (testimoniale sau recenzii), tagul <strong> pentru a marca diferite cuvinte cheie în interiorul conţinutului iar pentru stilizarea textului se vor evita pe cât posibil tagurile <b> și <i>, folosind proprietăţile CSS <font-weight> și <font-style>.

Redirectarea adresei non-www către adresa www

Redirectarea 301 este un tip de redirec-tare permanentă care va permite trecerea a peste 90% din optimizarea și beneficiile

SEO ale domeniului redirectat către noul domeniu. În general, se va folosi acest tip de redirectare în cazul mutării unui site pe un alt domeniu, fără a pierde foarte mult din traficul organic venit de pe Google. De foarte multe ori, se trece cu vederea faptul că adresa www.exemplu.ro și exem-plu.ro sunt văzute ca fiind diferite de către motoarele de căutare, iar puterea SEO a linkurilor externe poate să fie înjumătăţită. Redirectarea de tip 301 a adresei exemplu.ro, către www.exemplu.ro ne va ajuta să avem un rank mai bun. Pentru a înţelege mai bine acest lucru, ne putem gândi că avem 50 de linkuri de pe blogurile unor prieteni către exemplu.ro și 50 de linkuri de pe diferite alte site-uri către www.exem-plu.ro. Cele 100 de linkuri se împart între două adrese diferite, dar printr-un simplu 301 redirect, putem avea 100 de linkuri către aceeași adresă, dublând astfel autori-tatea sitului nostru. Acest tip de redirectare se poate realiza prin intermediul panoului de control al contului de hosting, prin folo-sirea unui fișier .htaccess în cazul siturilor construite folosind PHP sau prin fișierul webconfig în cazul siturilor care folosesc tehnologii Microsoft.

ConcluziiUn lucru foarte important de știut

este că optimizarea excesivă poate avea un impact negativ asupra site-ului, după

introducerea actualizării Pinguin, des-pre care am vorbit în numărul precedent. Folosirea exactă a aceluiași cuvânt sau grup de cuvinte în tagurile meta, în titlul paginii, în tagul <h1> dar și în interiorul conţi-nutului poate duce la o penalizare. Este recomandat să folosim mai multe variaţii ale unui cuvânt cheie sau construcţii modi-ficate ale unui anumit grup de cuvinte. Deși majoritatea acestor tehnici par, la o primă vedere, a fi simple, ele oferă un mare plus în optimizarea pentru motoarele de căutare. Ramura internă a SEO ţine în principal de acţiunile persoanelor care construiesc sau deţin un site, nu de factori externi, iar acest lucru ne face să le acordăm o atenţie sporită și ne oferă încrederea că rezultatele vor fi reale. În numărul viitor, vom veni în com-pletarea acestui articol cu o serie de tehnici de optimizare internă.

Tehnici SEO interne - partea Iprogramare programare

13www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

Google Guice

Servleții vor ”beneficia” de următoarele avantaje:• Injectare la nivel de constructor,• Configurare Type-safe,• Modularizare,• AOP.

Voi prezinta în acest articol două scenarii: • Dezvoltarea de la 0 a unei aplicații

web, • Intergrarea într-o aplicație existentă.

Start-ul unei aplicatii web folosind Google Guice

Aveți în dreapta un snapshop din Eclipse cu structura proiectului. Pe lângă librăriile Guice core prezentate în articolul trecut, classpath-ul trebuie să conțină și librăria guice-servlet.jar (Verificați sfârșitul aritcolului pentru dependința de Maven).

După ce classpath-ul este configurat, primul pas îl reprezintă definirea filtrului de Guice în web.xml. Aceasta va fi de altfel și singura configurare pe care o va conține acest fisier. Web.xml:

<?xml version=”1.0” encoding=”UTF-8”?><web-appxmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation= ”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee /web-app_3_0.xsd”version=”3.0”>

<display-name>Guice Web</display-name> <filter> <filter-name>guiceFilter</filter-name> <filter-class> com.google.inject.serv let.GuiceFilter </filter-class>

</filter> <filter-mapping> <filter-name>guiceFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping></web-app>

Ne-am asigurat astfel că toate requestu-rile vor fi procesate de Guice.

Următorul pas îl reprezintă constru-irea Injector-ului și definirea modulelor. Pe lângă modulele „obișnuite” care pot fi prezente în aplicație - descrise în arti-colul trecut , pentru a folosi într-adevar modulul de Guice Servlet trebuie să instalăm o instanță de com.google.inject.servlet.ServletModule. Acest modul este

Așa cum am promis în articolul trecut, voi continua prezetarea containerului Google Guice și pentru aplicații web. Pentru aceasta aveți nevoie de extensia de Servlet – parte din distribuția standard, alături de alte extensii precum JMX,

JNDI, Persist, Struts sau Spring. Folosind Guice web.xml-ul se reduce doar la punerea containerului Guice în ”mișcare”, restul configurarilor făcându-se simplu în codul Java în maniera type-safe prezentată în articolul trecut.

Mădălin [email protected]

Cluj Java Discipline Lead@ Endava

programare

14 nr. 5/2012 | www.todaysoftmag.ro

responsabil pentru setarea scopurilor de Request si Session și este locul unde vom configura servleții si filtrele folosite în aplicație.

Având în vedere ca dezvoltăm o aplicație web, cel mai logic loc în care putem crea Injector-ul îl repre-z i nt ă u n S e r v l e t C onte x t Li s t e n e r . ServletContextListener-ul este o compo-nentă care actionează imediat ce aplicația a fost instalată și înainte de orice request către server. Guice vine cu o clasă pro-prie ce trebuie extinsă pentru a putea crea un Injector valid. Vom folosi Servlet 3.0 API așa că vom adnota această clasă cu @WebListener – astfel nu va mai fie nevoie să o declarăm în web.xml.

Spuneam că ServletModule este locul în care configurăm servleții aplicației. Iată mai jos conținutul clasei care va extinde acest modul și configurează un servlet sim-plu mapat pe toate request-urile .html:

package endava.guice.modules;import endava.guice.servlet.MyServlet;

import com.google.inject.servlet.ServletModule;

public class MyServletModule extends ServletModule {

@Overrideprotected void configureServlets() { serve(„*.html”).with(MyServlet.class); }}

ServletContextListener-ul va avea urmă-torul conținut:

package endava.guice.listener;import javax.servlet.annotation.WebListener;import endava.guice.modules.MyServletModule;

import com.google.inject.Guice;import com.google.inject.Injector;import com.google.inject.servlet. GuiceServletContextListener;

@WebListenerpublic class MyGuiceConfig extends GuiceServletContextListener {

@Overrideprotected Injector getInjector() { return Guice.createInjector(new MyServletModule()); }

Observați în metoda getInjector() cre-area Injector-ului pe baza modulului de servlet de mai sus. Dacă aplicația are mai multe module, toate trebuiesc declarate aici – acesta e singurul loc în care trebuie creat un Injector. De asemenea, observați cât de intuitivă este și declararea Servlet-ului si a mapării aferente. Iată și conținutul clasei MyServlet:

package endava.guice.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import endava.guice.service.MyService;import com.google.inject.Inject;

import com.google.inject.Singleton;

@Singletonpublic class MyServlet extends HttpServlet {private static final long serialVersionUID = 1861227452784320290L;

@Inject private MyService myService;

protected void service( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println( „Service: „ + myService.doStuff()); }}

Haideți să analizăm puțin codul de mai sus:

1. Un servlet trebuie să fie singleton – marcat corespunzător prin adno-tarea @Singleton – altfel aplicația va arunca o excepție.

2. Folosim injectare la nivel de câmp pentru a obține o instanță de MyService care este apelată mai jos în metoda service().

3. Clasa extinde HttpServlet, ca orice alt servlet.

Interfața MyService:package endava.guice.service;import com.google.inject.ImplementedBy;

@ImplementedBy(MyServiceImpl.class)public interface MyService {

String doStuff(); }

Implementarea MyServiceImpl:package endava.guice.service;

public class MyServiceImpl implements MyService {

@Overridepublic String doStuff() { return „doing stuff!”; }}

În acest moment aplicația este gata pentru a fi deployată. Iată rezultatul unui request către index.html

Integrarea Google Guice într-o aplicație web existentă

Pentru a integra Google Guice într-o aplicație existentă vom începe prin a ne asigura că avem totul ”in place”. Pentru aceasta facem exact aceleași setări ca mai sus:• Adăugăm în classpath librăriile de

google guice• Definim filtrul în web.xml• Definim ServletContextListener-ul

p r i n s u b - c l a s a r e a c l a s e i

GuiceServletContextListener.Toate aceste configurări nu vor avea

momentan nici o influență asupra aplicației – totul va functiona la fel ca înainte, fără nici o problemă. În continuare putem avea două abordări: • Folosim Guice doar pentru ce este

nou adăugat – bineînțeles, nu este un best practice, dar este un caz des-tul de întâlnit în aplicațiile mari care au foarte mult legacy code,

• „Guice-ficăm” toata aplicația – cazul ideal.

Pentru cazul 2, abordarea va fi identică cu prima parte a articolului.

În primul caz vom ajunge în situații în care vrem să folosim DI în servleți sau clase care nu sunt instrumentate de Guice. Putem avea acces la Injector-ul de Guice foarte simplu prin accesarea ServletContext-ului:

Injector injector = (Injector) request.getServletContext(). getAttribute(Injector.class.getName());

Pentru injectarea dependințelor, folo-sind injectorul de mai sus, avem două posibilități:• U n c a l l c ă t r e i n j e c t o r .

injectMembers(this) – care va injecta toate dependințele,

• U n c a l l c ă t r e i n j e c t o r .getInstance(clazz) pentru fiecare instanță injectată.

Request and Session ScopeExtensia de Servlet introduce două sco-

puri noi: Request și Session. Voi arăta mai jos un exemplu despre folosirea scopului Session.

Vom modifica foarte puțin câteva din clasele prezentate mai sus. Având în vedere că în acest exemplu vom mixa și com accesa un obiect cu un scop mai restrâns dintr-unul cu un scop mai larg (accesăm un obiect cu scopul Session dintr-un sin-gleton), vom folosi Provideri (vezi Note).

Modulul de servleți va arăta astfel:

package endava.guice.modules;

import endava.guice.provider.PojoProvider;import endava.guice.servlet.MyServlet;import endava.guice.servlet.PojoClass;

import com.google.inject.servlet.ServletModule;import com.google.inject.servlet.ServletScopes;

public class MyServletModule extends Servlet-Module {

@Overrideprotected void configureServlets() { serve(„*.html”).with(MyServlet.class); bind(PojoClass.class). toProvider(PojoProvider.class). in(ServletScopes.SESSION); }}

programareprogramare

Google Guice

15www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINEprogramare

O bs er vaț i mai sus binding-u l ServletScopes.SESSION.

Clasa PojoProvider:package endava.guice.provider;

import endava.guice.servlet.PojoClass;import com.google.inject.Provider;

public class PojoProvider implements Provider<PojoClass> {

public PojoClass get() { return new PojoClass(); }}

Clasa PojoClass:package endava.guice.servlet;

public class PojoClass {

private String name;

public void setName(String s) { this.name = s;}

public String getName() { return this.name; }}

Pentru a demonstra că aplicația chiar functionează, vom modfica și clasa MyServlet să afișeze informații adiționale:

package endava.guice.servlet;import java.io.IOException;

import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import endava.guice.service.MyService;

import com.google.inject.Inject;import com.google.inject.Provider;import com.google.inject.Singleton;

@Singletonpublic class MyServlet extends HttpServlet {

private static final long serialVersionUID = 1861227452784320290L;

@Injectprivate Provider<PojoClass> pojoClass;

@Injectprivate MyService myService;

protected void service( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

response.getWriter().println( „Service: „ + myService.doStuff() + „ with „);

if (pojoClass.get().getName() == null) { pojoClass.get().setName(„name”); } else {

pojoClass.get().setName(„existing name”);}response.getWriter(). println(pojoClass.get(). getName()); }}

Pentru demonstrație o să accesăm aplicația de două ori. Prima dată ar trebui sa aveți rezultatul de mai jos:

Iar a doua oară următorul rezultat:

Exemplul poate fi foarte ușor schim-

bat pentru a folosi Request Scope in loc de Session Scope.

Așa arată o aplicație didactică în care am încercat să ating cele mai importante puncte din modulul de Guice Servlet. La fel cum am menționat și în articolul trecut, aceasta e doar o introducere. Puteți conti-nua să experimentați diverse situații. Cel mai mult veți învăța însă folosind Guice într-un proiect ”pe bune”.

Guice ca și Maven dependency

<dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>3.0</version></dependency>

ProvideriProviderii adresează următoarele

situații:• Un client are nevoie de mai multe

instanțe ale unei dependințe per injection,

• Un client vrea să obțină dependința efectivă doar atunci când se face injectarea (lazy loading),

• Injectăm un obiect cu scop mai restrâns într-un obiect cu scop mai larg,

• Avem logică adițională necesară pentru crearea unui obiect care va fi apoi injectat,

• Vrem să controlăm modul în care sunt create instanțele pentru binding.

După cum am văzut mai sus, este foarte simplu să scriem un Provider. Trebuie doar să implementăm interfața Provider<T>, unde T este tipul concret pentru care vrem să construim provider-ul.

16 nr. 5/2012 | www.todaysoftmag.ro

Agile & Testing & Mobile trei concepte convergente

Într-un timp relativ scurt, apariția acestor aplicații ne-a determinat să folosim telefonul mobil sau tableta până și în cele mai puţin importante activități pe care le desfășurăm de-a lungul zilei.

Pe măsură ce nevoile clienților au evo-luat, dezvoltatorii de aplicații mobile au început să se axeze foarte mult pe com-plexitatea aplicației, neglijând oarecum calitatea acesteia. Datorită cerințelor prea mari ale clienților, multe proiecte au înce-put să aibă probleme în ceea ce privește alocarea timpului necesar dezvoltării și testării aplicațiilor.

Ca o soluție pentru această problemă putem discuta despre alegerea unei meto-dologii de dezvoltare care să cuprindă cât mai bine cerințele clienților și să protejeze timpul și munca echipei de dezvoltare.

Stabilirea unor standarde care trebuie urmate se face la nivel de companie și tre-buie aplicate sau modificate asfel încât să se adapteze cât mai bine cerințelor clientului și a produsului care urmează să fie livrat.

Folosind metodologia “Agile”, compa-nia pentru care lucrez a reușit să definească câteva reguli sau principii de bază care tre-buie urmate pentru a livra un produs cât mai apropiat cerințelor clientului și a pieței.

Aceste principii de bază ar fi:• Definirea strategiei de testare,• Definirea scopului testării,• Adaptarea continuă la schimbarea

scopului,• Identificarea riscurilor și stabilirea

strategiei de prevenire,• Feedback-ul continuu.

În cele ce urmează vom detalia fiecare dintre aceste reguli având în vizor lumea aplicaţiilor mobile și analizând impactul fiecăreia în dezvoltarea produsului.

Definirea strategiei de testareChiar dacă nu avem cum să știm ce

“surprize” sau impedimente vom întâlni pe parcursul testării unei aplicații, este esențial să stabilim de la bun început o bază a strategiei de testare. Aceasta bază are ca principale componente:• Stabilirea ariei testării,• Determinarea mediului de testare,• Definirea tipurilor de teste ce se vor

aplica.

Aria de testareClientul joacă un rol foarte important

în stabilirea ariei de testare (dispozitive, sisteme de operare, combinații ale platfor-melor, browsere etc.). Echipa responsabilă de Quality Assurance (QA) trebuie să pre-zinte clientului riscurile unei arii de testare reduse sau posibilele riscuri care vor apărea în momentul în care aplicația se află deja în dezvoltare. Pentru a putea prezenta aceste date, echipa trebuie să efectueze câteva cer-cetări pe piață pentru a stabili care sunt cele mai folosite dispozitive și sisteme de ope-rare. În urma unor discuții client- echipă se pot stabili următoarele:• Care sunt platformele pe care se va

face dezvoltarea;• C a r e s u n t d i s p o z i t i v e l e ș i

combinațiile de sisteme de operare pe care se va axa testarea;

O privire de ansamblu asupra universului IT al zilelor noastre ne arată că tehnolo-gia mobilă este un domeniu deosebit de dinamic. Bătălia principală de pe acest sector de piață se desfășoară între trei mari competitori: Apple, Nokia și marea

familie a dispozitivelor cu Android (Samsung, Motorola, Sony-Ericsson etc.). Dacă până nu demult pe un dispozitiv mobil aveam la dispoziţie doar aplicații de bază (clienți de e-mail, navigatoare, calculator de buzunar sau jocuri rudimentare) astăzi suntem bombardați din toate direcțiile de aplicații financiare, sănătate și asigurări, jocuri cu grafică avansată, calendare și agende avansate, asistent personal.

testare

Rareș Irimieș[email protected]

Senior QA @ 3Pillar Global Romania

management

17www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

• Care este posibilitatea ca opera-torii de telefonie sau fabricanții de dispozitive să fi implementat functionalități comune de care ar depinde aplicația care urmează să fie dezvoltată.

Datorită timpului sau bugetului limitat, testarea efectivă nu va putea acoperi sufi-ciente dispozitive și versiuni de sisteme de operare pentru a putea reduce considerabil numărul defectelor. În acest caz, este indicat ca testarea să se desfășoare pe combinațiile de dispozitiv - sistem de operare cele mai folosite și pe dispozitivele la care s-au sem-nalat cele mai multe probleme.

Un alt pas important în stabilirea ariei de testare este poziționarea aplicației pe piață: jocuri, social, banking, sănătate etc. Bazându-ne pe segmentul de piață pentru care este adresată aplicația, putem stabili câteva dispozitive care vor fi folosite în tes-tare. Astfel, pentru banking vom fi nevoiți să acoperim cât mai multe dispozitive pen-tru ca orice fel de utilizator să aibă accces la ea, iar pentru jocuri ne vom orienta spre dispozitivele cele mai utilizate de către copii (iPod, iPad , Android tablet).

O altă problemă care ar putea apărea în momentul în care dezvoltăm o aplicație complexă este folosirea unor API-uri furi-zate de aplicaţii deja existente (Facebook, Twitter, etc) sau a unor librării third-party (TapJoy, iAD etc). Clientul trebuie să știe că integrarea acestor componente poate dura mai mult sau poate avea un impact major asupra stabilităţii aplicației (bug-uri third-party care nu pot fi rezolvate în timp

util sau a caror soluţii de evitare pot afecta într-un mod neplăcut funcționalitatea aplicației).

Mediul de testare Odată ce aria de testare a fost stabilită,

urmează definirea mediului testării. În cadrul aceste activități trebuie să avem în vedere următoarele aspecte:• Ce tip de testare vom folosi?• Care sunt costurile pentru procura-

rea acestui mediu?• Cât de eficientă este testarea pe un

astfel de mediu?• Odată mediul creat, putem să îl folo-

sim și pentru testarea altor aplicații?

Astfel putem face o comparație între urmatoarele medii de testare: emulatoare – dispozitive fizice – infrastructură partajată.

– Shared infrastructure

EmulatoareFiind cele mai la îndemână, testarea pe

emulatoare are niște caracteristici ce tre-buie luate în seamă atunci când se aleg ca mediu principal de testare:• Emulatoarele sunt eficiente în:

Sanity testing, Compatibility testing, Functional testing, Smoke testing;

• Sunt gratuite (download free) ; • 40% din testarea aplicației poate fi

executată pe emulator;• Se pot obține combinații dorite de

dispozitiv - sistem de operare ; • Nu sunt 100% eficiente în crearea

unui scenariu de zi cu zi;• Sunt medii de testare relativ încete;

• Sunt intens utilizate în testarea automată.

Infrastructură partajatăAceastă modalitate are câteva caracte-

ristici ce merită menţionate:• Eficiente în: Exhaustive testing,

Compatibility testing, Interruption testing, Functional testing, Regression testing;

• Nu este free (DeviceAnywhere, PerfectoMobile);

• Testarea poate acoperi o gamă largă de combinaţii dispozitiv – sistem de operare;

• Foarte încete din cauza utilizării conexiunii la internet pe întreaga perioadă a testării;

• Eficiente în reproducerea unui sce-nariu de zi cu zi.

Dispozitive fiziceTestarea într-un astfel de mediu poate

fi considerată cea mai aproape de adevăr având în vedere faptul că poate fi simulat perfect comportamentul uman în folosirea dispozitivelor. Caracteristicile importante sunt în acest caz următoarele:• Eficiente în: Functional testing,

Smoke testing, Acceptance testing, Regression testing, Bug fix testing;

• Foarte bune pentru reproduce-rea problemelor apărute în timpul utilizării;

• 50% din testarea trebuie facută pe un dispozitiv fizic;

• Eficiente în testarea automată;• Oferă rezultate rapide și precise.

management

18 nr. 5/2012 | www.todaysoftmag.ro

Tipul testăriiDupă definirea mediului de testare,

echipa trebuie să decidă tipul de testare uti-lizat. Fie ea manuală sau automată, testarea trebuie adaptată complexității proiectului, bugetului alocat pentru resurse precum și timpului de testare disponibil.

Astfel, făcând o comparație între aceste tipuri de testare manuală sau automată, trebuie să luăm în considerare următoarele aspecte.

Care este cea mai bună metodă de testare?

Testarea manuală are o eficiență de 100%, deoarece comportamentul utili-zatorului poate fi reprodus cel mai ușor. Testarea automată are o eficiență de doar 60-70%, deoarece script-urile folosite nu pot fi 100% corecte sau complete. Totodată, testarea manuală ar trebui efectuată în procent de minim 70% pe întregul pro-iect. Pe marginea subiectului Manual vs Automation au loc în prezent o serie de dezbateri care au drept concluzie, în mare parte, faptul că testarea automată nu poate înlocui testarea manuală.

Care sunt costurile fiecărei metode?Pentru a răspunde scurt la această

întrebare, trebuie să avem în vedere com-plexitatea aplicației și timpul acordat pentru testare. Testarea automată costă mai mult în faza iniţială în care se inves-tește timp și resurse pentru dezvoltarea script-urilor automate, setarea și utiliza-rea unui mediu de Continuous Integration, însă în timp această metodă își va dovedi eficienţa în etapele de testare de regresie. Pe de altă parte, testarea manuală este capa-bilă de a descoperi defectele încă din fazele incipiente ale produsului; în schimb este costisitoare din punctul de vedere al dispo-zitivelor fizice pe care aceasta se desfășoară.

Care sunt beneficiile acestui tip de testare?

Testarea automată poate fi foarte folosi-toare în faza de testare de regresie, salvând mult timp de execuție a testelor. Cu toate acestea, joacă un rol foarte important în load testing sau performance testing pe întreaga durată a proiectului. Bineînteles, dupa cum am spus anterior, în cazul tes-tării automate trebuie luată în considerare posibilitatea integrării într-un sistem de Continuous Integration (ex. Bamboo, Jenkins/Hudson etc).

Principalele metode de testare pentru testarea manuală sunt Functional testing și Bug-fix testing. Punctele urmărite în testa-rea manuală ar fi:

a. Testarea interfeţei cu utilizatorul, care implică fonturi, culori, naviga-rea de pe un ecran pe altul;

b. Testarea functionalităților de bază ale aplicației;

c. Usability testing – implică testarea butonalor gen “Home” sau “Back” din fiecare ecran al aplicației;

d. Testarea download-ului, instalării sau dezinstalării aplicației;

e. Interruption testing – Felul în care se comporta aplicația în momentul când primești un mesaj sau un apel, iar aplicația rulează in foreground;

f. Monkey testing – inserarea de carac-tere sau imagini într-un mod haotic pentru a vedea care este rezistenţa aplicației la stres;

Pe lângă testarea manuală sau auto-mată, din ce în ce mai multe companii apelează la servicii de gen “Crowd sour-cing”. Folosindu-ne de aceste servicii putem stabili dacă am construit produsul corect, transferându-l spre testare unui grup de oameni care fac parte din viitorii utilizatori (alfa testing).

Strategia de testareAvând clarificate cele trei componente

ale testării detaliate anterior (aria testării, mediul de testare și tipul testării) se poate defini o strategie de testare a unei aplicații mobile în patru pași:

1. Plana. Înţelegerea documentaţiei și a

cerinţelorșb. Stabilirea dispozitivelor si a com-

binaţiilor cu sistemele de operare;c. Descrierea emulatoarelor sau dis-

pozitive reale de testarii;d. Descriere tipului de testare (auto-

mat sau manual) folosit.2. Design

a. Găsirea uneltelor adec vate (pentru Automation, Test Case Ma n a g e m e n t , C o n t i n u o u s Integration);

b. Rezolvarea problemei dispozitive-lor (procurarea acestora);

c. Stabilirea scenariilor de test;3. Dezvoltare

a. Crearea datelor de test;

b. Crearea scenariilor de test;4. Executare

a. Configurarea mediului de testare;b. Testarea efectivă;c. Reportarea defectelor;d. Extragerea de rapoarte (Execution

Matrix).

Definirea scopului testăriiÎn metodologia Agile-Scrum, procesul

de QA se desfășoară pe întreg parcursul proiectului, în fiecare sprint. La sfârșitul fiecărui sprint, fiecare aplicație trebuie să aibă un cod compilabil care poate fi testat. Dat fiind că în majoritatea cazurilor timpul alocat pentru QA este de 2-4 zile, planul de testare trebuie să fie foarte clar și să defi-nescă gradul de calitate pe care îl va avea codul în momentul Demo-ului.

În primele sprint-uri (în care se imple-mentează în general functionalități noi) testerul va putea valida doar “happy flow”-ul. Pe măsură ce codul devine tot mai stabil, vor apărea și posibilitățile de testare automată, testare a performanței și a scena-riilor negative. În funcție de complexitatea produsului, managerul trebuie să aloce 1-2 sprint-uri pentru testare și bug-fixing îna-inte ca produsul să fie instalat pe mediul de producţie și să ajungă public.

Adaptarea continuă la schimbarea scopului

Această regulă este una destul de incomodă pentru majoritatea testerilor. Deoarece în “Agile” prioritățile sau funcţi-onalitatea aplicației se pot schimba, planul de testare trebuie actualizat cât mai des pentru a reflecta schimbările petrecute.

De exemplu, se ia decizia ca anumiţi utilizatori să poată avea acces la partea de backend a aplicației pentru a adăuga sau șterge conturile altor utilizatori, acest lucru nefiind prezentat în documentația inițială a aplicației. În acest caz, în planul de testare vor trebui introduse noi metode de testare: • Security testing (în funcție de rolul

utilizatorului, acesta are sau nu acces la întreaga baza de date);

• Load testing (verificarea comporta-mentului în condițiile în care mai mulți utilizatori alterează baza de date în același timp).

Acesta este doar un exemplu, însă des-chiderea pentru schimbarea permanentă a scopului și a metodologiei trebuie să fie prezentă constant.

testareAgile & Testing & Mobile - 3 concepte convergente

19www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

Identificarea riscurilor si stabilirea strategiei de abordare

Este foarte important ca planul de tes-tare să surprindă și să prevadă cât se poate de bine riscurile care pot apărea pe parcur-sul dezvoltării și testării produsului.

De exemplu, pentr u a testa o funcționalitate mai complexă este necesar să alocăm mai mult timp pentru testare. Strategia de abordare și prevenire a riscuri-lor ar putea consta în alocarea mai multor resurse pe o perioadă scurtă de timp pentru a testa cat mai multe scenarii de risc care ar putea fi executate de către un utilizator, sau poate însemna în același timp reducerea numărului de teste și prioritizarea acestora în funcţie de impactul asupra aplicaţiei.

Feedback-ul continuuPoate cel mai important lucru și nu

în ultimul rând, trebuie avută o discuție

deschisă și continuă pentru a obține feedback. Este foarte important ca noile functionalități sau schimbări majore aduse aplicației să fie discutate de către toate persoanele implicate în proiect pentru a obține calitatea dorită. Aceste modificări au un impact foarte mare asupra planului de testare și a calității produsului existent. Pentru aceasta, persoanele din departa-mentul de testare trebuie să fie implicate în luarea decizilor de acest tip de către client sau de către echipa de dezvoltare.

În sprijinul acestei reguli poate fi adusă și ideea testării încă din primele faze ale proiectului și implicarea cât mai mare nu doar a testerilor dar și a managerului de produs în procesul de calitate. Calitatea produsului trebuie să fie asigurată în mod colaborativ și fiecare persoană implicată în dezvoltare trebuie să fie conștientă de cali-tatea pe care o produce.

ConcluziiTestarea aplicațiilor mobile devine din

ce în ce mai dificilă odată cu trecerea tim-pului, creșterea nivelului de complexitate al aplicației și pretențiile tot mai mari ale clienților. Alegerea strategiei corecte atât în ceea ce privește tipurile de testare cât și mediul pe care aceasta se desfășoară ne ușureaza munca, reduce costurile și poate ajuta în anticiparea problemelor ce ar putea să apară. Poate cel mai important lucru este deschiderea permanentă către schim-bare și adaptarea continuă la scopul mereu ajustabil.

Testarea aplicaţiilor mobile este o pro-vocare în sine, mediul mobil fiind cel mai dinamic în zilele noastre.

20 nr. 5/2012 | www.todaysoftmag.ro

Design-ul aplicaţiilor Android pentru toate platformele

Una dintre problemele, cu care se con-fruntă programatorii aplicaţiilor Android este lansarea unei aplicaţii care să funcţio-neze corect pe toate platformele suportate. Ceea ce merge perfect pe unele telefoane ar putea să nu funcţioneze deloc pe altele, acest lucru făcându-i pe unii să renunţe la încercarea de a acoperi o categorie cât mai largă de telefoane Android, inclusiv tablete.

Principalele constrângeri care trebuie luate în considerare atunci când se scrie o aplicație sunt:• versiunea de SDK suportată,• opţiunile de configurare la rulare

cum ar fi: limba, orientarea tele-fonului (portret sau landscape), operatori, etc,

• versiunile de hardware diferite, fie-care cu constrâgerea sa,

• dimensiunea telefonului sau a tabletei.

Constrângeri graficeUn loc aparte în proiectarea și dezvolta-

rea unei aplicații îl ocupă arhitectura părţii grafice cu scopul de a acoperi cât mai multe tipuri de telefoane.

Interfaţa grafică trebuie construită dinamic, pentru a fi schimbată în funcţie de

așteptările și nevoile utilizatorilor; limbajul vizual trebuie să fie dus dincolo de ecranele statice pentru o utilizare cât mai flexibilă a elementelor vizuale. Nu este suficientă crearea de aplicaţii cu un UI performant - care reacţionează rapid la acţiunea uti-lizatorului - ci și intuitiv, astfel încât toate elementele să fie clare și complet vizibile.

Din fericire, framework-ul Android se dezvoltă continuu în această direcţie, și anume în a oferi suport în dezvoltarea aplicaţiilor pentru mai multe tipuri de telefoane. Toate modelele grafice pe care fiecare versiune de SDK le aduce nu trebuie considerate restricţii, ci moduri de dezvol-tare în această direcţie.

Încă de la început, framework-ul de UI a fost proiectat pentru a putea fi ajustat în funcţie de spaţiul ecranului care există la dispoziţie. Un exemplu la îndemână ar fi componenta ListView care poate să își schimbe înălţimea în concordanța de dime-nisunea ecranului, care variază în funcție de QVGA HVGA și WVG.

Design grafic pentru telefoanePartea grafică este construită cu ajuto-

rul fisierelor .xml, numite layout-uri.Înc e p ând c u And roi d 1 . 6 s - a

Chiar de la inceput aș vrea să subliniez faptul că acest articol nu aduce ceva nou la modul de programare în Android, ci este mai degrabă o sinteză a informaţiei pe care sistemul Android o pune la dispoziţie.

Claudia Dumitraș[email protected]

Android Developer @ Skobbler

managementprogramare

21www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

introdus un nou concept, acela de densitate a ecranului, făcând astfel mult mai ușoară scalarea pe mai multe rezoluţii, chiar și când telefoanele aveau aproximativ aceeași dimensiune fizică (spre exemplu această opţiune a fost extrem de utilă pentru tele-foanele gen Droid, cu rezoluţii mari, ce au apărut pe piaţă). Prin densitatea ecranului se înțelege numărul de pixeli pe o anumită suprafaţă a ecranului fizic, sau altfel spus, puncte per inch (dots per inch). Astfel, par-tea grafică (layouts) poate fi clasificată în: „small” pentru QVGA, „normal” pentru HVGA și „large” pentru WVGA, în acest fel putându-se folosi diferite resurse în concordanța cu dimensiunea ecranului. În funcție de aceste calificative de configurare prezente în aplicaţie, sistemul știe să aleagă resursele potrivite în funcţie de caracteris-ticile specifice ecranului telefonului. Un calificativ de configurare reprezintă string-ul adăugat fișierelor de resurse.

Exemplul de mai jos prezintă o listă cu nume de fișiere pentru resurse, în funcție de diferite layout-uri precum și exemple de fișiere diferite de imagini pentru densități de ecran „small”, „normal” și „high”: // layout pentru dimensiunea ecranului „normal”res/layout/my_layout.xml

// layout pentru dimensiunea ecranului „small”res/layout-small/my_layout.xml

// layout pentru dimensiunea ecranului „large”res/layout-large/my_layout.xml

// fisier imagini pentru densitatea mică „low”res/drawable-ldpi/my_icon.png

// fisier imagini pentru densitatea medie // „medium”res/drawable-mdpi/my_icon.png

// fisier imagini pentru densitatea mare „heigh”res/drawable-hdpi/my_icon.png

Chiar dacă aplicaţia va dispune de

mai multe directoare de resurse, este bine a se folosi anumite standarde în toate layout-urile existente și anume, este indicat a se folosi dps ca unitate de măsurare (densitatea indepen-dentă de pixeli). Un dp este o unitate vir-tu a l ă , c are d e s c r i e dimenisunea, precum și poziţionarea elementelor grafice, într-o manieră independentă de den-sitate. Un dp este egal cu un pixel fizic pe un ecran de 160 dpi (dots per inch), aceasta fiind densita-tea de referinţă presupusă de sistem pentru o densi-tate de ecran „medium”. La runtime, dacă este necesar, sistemul decide scalarea unităţilor dp, bazat pe densitatea actuală a ecranului utilizat.

Design grafic pentru tabletePentru prima generaţie de tablete cu

Android 3.0, modul potrivit de a declara partea grafică este folosind calificativul de configurare „xlarge” (de exemplu res/layout-xlarge/).

Cu scopul de a suporta și alte tipuri de tablete cu alte dimensiuni, de genul celor de 7” – Android 3.2 a introdus o nouă modalitate de a împărţi resursele. Această nouă tehnică se bazează mai degrabă pe raţionalizarea spaţiului necesar, decât pe

încercarea de a face ca layout-urile să fie generalizate pe grupuri de dimensiuni (cum ar fi large sau xlarge) . Chiar dacă cele două tipuri de tablete par a fi apropiate în dimensiuni, separarea tabletelor de 7” de cele de 5” a fost necesară, mai ales pen-tru că acestea două se încadrau în grupul „telefoanelor mari” (large). Spaţiul ecranu-lui utilizat la aceste două tipuri de tablete este diferit, la fel este și stilul cu care sunt obișnuiţi utilizatorii.

Pentru ca diferenţierea părţii grafice să fie și mai bine proiectată pe diferite dimen-siuni, platforma Android permite acum gruparea resurselor specificate în dp, bazat

management

W E W A N T Y O UA N A W E S O M E C + + D E V E L O P E R

T O A P P LY !N O W I T ’ S T I M E&

to work with the latest kick-ass technologiesto do some serious rocket science with more than 3 mio customers, who drive 2 mio km/week

to rock the Romanian IT industryto change the LBS community worldwide

www.skobbler.com/[email protected]

Figura 1 Strategii de a trata design-ul layout-urilor pentru tablete portet şi landscape.

Sursa: http://static.googleusercontent.com/external_content/

untrusted_dlcp/www.google.com/en//events/io/2011/static/presofiles/

designing_and_implementing_android_uis_for_phones_and_tablets.pdf

22 nr. 5/2012 | www.todaysoftmag.ro

pe lăţimea și/sau înălţimea care sunt cu adevărat disponibile pentru aplicaţie. De exemplu, după proiectarea layout-urilor pentru tablete, se poate determina limita pentru care acest layout nu se mai potri-vește, de exemplu 600dp. Această limită, astfel setată, devine dimensiunea minimă necesară pentru layout-ul tabletelor sau, altfel spus, acest tip de resurse este specifi-cat atunci când există cel puţin o lăţime de 600dp pentru UI-ul aplicaţiei.// pentru tablete de 7” (laţime mai mare sau // egală cu 600dp)res/layout-sw600dp/main_activity.xml // pentru tablete de 10” (laţime mai mare sau // egală cu 720dp)res/layout-sw720dp/main_activity.xml

De obicei, pentru tablete se dorește folosirea întregului spaţiu aflat la dispoziţie și extinderea elementelor grafice pe toată lungimea ecranului, ceea ce nu duce întot-deauna la un rezultat plăcut. O soluţie la îndemână constă în împărţirea layout-ului

general în panouri mai mici, tehnică numită și multi-p a n e . A c e a s t ă separare trebuie făcută într-un mod ordonat ș i clar, astfel încât con-ţinutul să devină mai detaliat, dar această împărţire trebuie să fie păs-trată indiferent de orientarea tabletei. În f igura urmă-toare sunt câteva strategii pe care cei de la Android le propun pentru

a rezolva eventua-lele probleme care apar în portret sau landscape.

FragmenteImplementarea panourilor multiple se

realizează cel mai ușor folosind fragmente (Fragment API). Un fragment poate repre-zenta o funcţionalitate aparte, sau o parte din interfaţa grafică. Se pot combina mai multe fragmente într-o singură activitate, cu scopul de a construi astfel o interfaţă cu panouri multiple. Acest lucru constituie un avantaj, pentru că se pot refolosi în diferite activitaţi. Fiecare sub-layout poate fi împăr-ţit pe fragmente. O clasă Fragment poate fi considerată ca mini-Activity (Activity - clasa specifică Android ca suport al părţii grafice), dar nu poate funcţioana indepen-dent, ci trebuie să fie inclusă în cadrul unei clase Activity. Un Fragment este o compo-nentă cu UI și cu durată de viaţă proprie, dar acest lucru este direct afectat de suc-cesiunea de stări a activităţii. De exemplu,

atunci când activitatea este terminată la fel vor fi și fragmentele componente. Cu toate acestea, fragmentele pot fi adăugate sau șterse în timp ce activitatea rulează.

Versiunea minimă de SDKVersiunea minimă a SDK este un atri-

but care se declară în fișierul manifest al aplicației (android:targetSdkVersion). De obicei acesta se alege în funcţie de numă-rul cel mai mare al telefoanelor existente pe piaţă. Acest număr reperezintă limita superioară a API-ului folosit și este foarte important pentru că ar putea influența anumite funcționalități. Cu cât numărul versiunii este mai mic cu atât mai mult pot apărea neplăceri legate de limitările date de API. De asemenea, multe din widget-urile native ar putea avea o imagine învechită.

ConcluzieEste important ca design-ul aplicației

să fie compatibil cu toate platformele existente, în acest fel crescând numărul utilizatorilor. Acest lucru, însă, nu este suficient. Fiecare dimensiune a ecranului oferă diferite posibilități și provocări pen-tru interacțiunea cu utilizatorul, așa încât pentru a impresiona cu adevărat, trebuie mers mai departe, și anume, trebuie opti-mizată această experiență pentru fiecare tip de configurare.

Chiar dacă nu veţi putea cumpăra toate device-urile existente pe piaţă la ora actuală, pentru a vă testa aplicaţia, siste-mul Android pune la dispoziţie multiple metode pentru a testa rezultatul final pe mai multe platforme. Dar înainte de aceasta, fiecare aplicaţie trebuie să respecte toate standardele impuse de acest sistem de operare.

Figura 2. Exemplu de definere a modulelor grafice care conțin fragmente, ce pot fi combinate într-o activitate pentru tablete, dar separate petru telefoane Sursa http://developer.android.com/guide/components/fragments.html)

Referinţehttp://developer.android.com/guide/practices/screens_support.htmlhttp://android-developers.blogspot.ro/2011/02/android-30-fragments-api.htmlhttp://developer.android.com/guide/components/fragments.htmlhttp://www.google.com/events/io/2011/sessions/designing-and-implementing-android-uis-for-phones-and-tablets.htmlhttp://static.googleusercontent.com/external_content/untrusted_dlcp/www.google.com/en//events/io/2011/static/presofiles/designing_and_implemen-

ting_android_uis_for_phones_and_tablets.pdfhttp://www.youtube.com/watch?v=2jCVmfCse1E&feature=relmfuhttp://developer.android.com/guide/topics/manifest/uses-sdk-element.htmlhttp://developer.android.com/training/multiscreen/index.html

Design-ul aplicaţiilor Android pentru toate platformele

managementprogramare

23www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

Formarea unei echipeEste ușor de conchis din principiile

Manifestului Agil că mișcarea agilă con-sideră oamenii ca fiind indivizi unici și nu resurse înlocuibile și că cea mai mare valoare adusă nu este în performanța individuală (chiar dacă ea joacă un rol important), ci rezultă din puterea interacțiunilor și colaborării între indi-vizi. Practicile agile recomandă formarea de echipe coezive, cu roluri bine definite, care se autoorganizează și care au ca scop ultim obținerea valorii. Acest lucru presu-pune, desigur, că membrii unei echipe sunt împuterniciți să facă lucrurile așa cum con-sideră ei cel mai bine, conform principiilor și ‚Crezului’ lor, fără să li se fi impus un anumit model de lucru. În egală măsură, aceasta înseamnă că aceștia sunt și respon-sabili pentru rezultatele si performanțele

lor. Formarea unei echipe agile, modul

cum sunt alocați oamenii într-o anumită echipă (în funcție de competențe, compa-tibilitate etc.), este crucial pentru succesul acesteia. Extrapolând, clădirea de echipe agile este foarte importantă pentru a dez-volta un mediu agil, deci o companie agilă și având ca ultim scop cultivarea unei mentalități agile. Voi detalia această per-spectivă mai încolo. Dar legat de chipă, contează foarte mult configurația acesteia, responsabilitățile membrilor ei și cum aceștia colaborează pentru a dezvolta relații de succes. Compatibilitatea membrilor unei echipe, modul cum ei interacționează sunt esențiale pentru a forma o echipă de succes.

Ideea de influențare și imitare a performanței este cea mai evidentă atunci când echipa nu a atins un anumit nivel de maturitate și când individul cu cea mai

Nu există o modalitate mai bună de a descrie chintesența mentalității agile decât pornind de la principiile Manifestului pentru dezvoltare agilă de software:

„Noi scoatem la iveală modalități mai bune de dezvoltare software prin experiență proprie şi ajutându-i pe ceilalți. Prin această activitate am ajuns să apreciem:

• Indivizii și interacţiunea înaintea proceselor și tool-urilor,• Software-ul funcţional înaintea documentaţiei vaste,• Colaborarea cu clientul înaintea negocierii contractuale,• Receptivitatea la schimbare înaintea urmăririi unui plan.

Cu alte cuvinte, desi există valoare in elementele din dreapta, le apreciem mai mult pe cele din stânga.”

agilemanifesto.org

management

Cum să crești o mentalitate agilă în

contextul dezvoltarii software?

Andrei Chirilă [email protected]

Team LeaderTechnical Architect@ ISDC

cu peste 5 ani de experienta, Andrei sustine ca motivatia si pasiunea sunt valori-nucleu pentru o echipa. Acesta este unul dintre motivele pentru care el considera ca, daca este interesant sa iti doresti a fi inspirat, este cu mult mai valoros sa tintesti sa ii inspiri pe ceilalti din jurul tau pentru ca asta ii ajuta pe acestia sa se dezvolte si pe tine sa te autodepasesti.”

24 nr. 5/2012 | www.todaysoftmag.ro

multă experiență este un model pentru toți ceilalți membri ai echipei. Puterea exem-plului este mult mai mare decât ne putem închipui. Atitudinea este foarte ușor imita-bilă pentru indivizi. Oamenii au tendința de a împrumuta comportamente de la cei cu care empatizează, de a copia atitudinea superiorilor sau de o respinge total, și de aceea, sunt foarte importante anturajul, echipa și contextul în care un individ interacționează și, în consecință, cum se ”crește” o echipă și o viziune colectivă.

Un citat anonim spune: ”Să fii inspirat este bine, dar să îi inspiri pe ceilalți este incredibil”. Un adevărat lider va fi recu-noscut de către ceilalți și îi va determina pe aceștia să își depășească limitele. Rolul acestui lider (eventual Scrum Masterul într-o implementare SCRUM) este critic pentru că acesta își poate motiva oamenii să performeze, dar trebuie să știe și să ii protejeze atunci când ceilalți au nevoie de asta.

Împuternicire și responsabilitateAdesea atitudinea oamenilor dintr-o

companie face diferența între o companie matură de una cu mai puțină experiență. O echipă devine mai productivă cu cât este mai responsabilă pentru ceea ce face și cu cât membrii ei sunt împuterniciți să hotărască ceea ce este cel mai bine pentru produsul lor și contextul în care lucrează.

Într-un cadru de lucru clasic, puterea pe care un manager o are asupra celorlalți, cunoașterea proiectelor și controlul asupra

deciziilor legate de proiecte sunt doar o ilu-zie pentru că acestea pot fi privite de către ceilalți ca o modalitate de a pasa responsa-bilitatea de la un nivel la altul. Managerul este informat, iar omul din echipă este indirect ”eliberat” de responsabilitatea de a hotărî.

Schimbarea de perspectivă este că, într-un mediu agile, motivul pentru a împuternici indivizii nu este pentru a motiva ci pentru a îmbunătăți managemen-tul decizional. Distribuirea informației și a responsabilității în cadrul unei rețele (de exemplu o echipă) este mult mai eficientă decât menținerea acestora la un singur individ. O echipă care consideră că are ca singur țel dezvoltarea de linii de cod fără a se implica activ în procesul decizional și fără a-și atribui responsabilitate nu poate fi considerată o echipă matură. Oamenii ar trebui să fie încurajați și împuterniciți să ia decizii cu informațiile la care au acces și motivați să clădească povești de succes, nu să se aștepte să fie călăuziți de oamenii de pe alte nivele către povești de succes.

Responsabilitatea și împuternicirea nu apar de la o zi la alta, însă pot fi ”cultivate”. Dacă a iniția acest proces de creștere este mai greoi, odată început, lucurile vor evo-lua de la sine până când un anumit nivel de maturitate este atins.

Echipele mature nu au nevoie de foarte multă mentenanță. Ele au suficientă experiență și informații contextuale pen-tru a fixa majoritatea problemelor cu care se confruntă. În egală măsură, ele trebuie

să își cunoască foarte bine limitele cercu-lui de influență și să ceară ajutorul atunci cand au nevoie. De aceea, un adevărat lider de echipă trebuie să își încurajeze echipa să vrea mai mult, să îndrăznească, să pro-voace schimbări și să se autodepășească, dar trebuie să ii protejeze în egală măsură de presiunea exterioară și de pericolul care poate apărea dacă aceștia își supraes-timează forțele.

Oamenii înaintea ProceselorEste important de remarcat că, în ciuda

faptului că manifestul agile sugerează pra-digma ‚oamenii înaintea proceselor’, acest fapt nu înseamnă că procesele nu aduc valoare în cadrul dezvoltării software. Dimpotrivă. Acestea ar trebui să com-plementeze Modelul Agil pentru că, deși diversele implementări de ‚Process Improvement’ (de exemplu CMMi etc.) vorbesc despre zonele care pot fi adresate pentru a eficientiza, ele nu dau o rețetă despre abordarea pe care o poți folosi în a le implementa. Aici poate interveni cu suc-ces modelul agil pentru că, în filosofia sa, este adresată tocmai nevoia de schimbare și perfecționare a modului de lucru prin pricipiul ‚inspectează și adaptează’.

Conform acestui principiu, echipa este atentă la lucrurile care nu sunt optime pen-tru ea și își setează ca țintă perfecționarea acestora prin dezvoltarea unor micropro-cese, procese care sunt relevante în echipă. În timp, acestea pot deveni macroprocese pentru că, dacă sunt împărtășite, pot aduc

management

Cum sa cresti o mentalitate agila in contextul dezvoltarii software?

management

25www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

valoare altor echipe și organizației. Cu cât acest lucru este făcut mai des de către echipe, cu atât comunitatea și organizația pot beneficia de pe urma acestora pen-tru că promovează învățarea din greșeli, împărtășirea de practici și formarea unei identități colective.

Cum ? Ce ? De ce ?Membrii unei echipe agile vor întâm-

pina provocări peste care vor trece, vor învăța și vor evolua. În urma acestor experiențe, își vor dezvolta noi procese, reguli și proceduri care îi vor ajuta să fie mai eficienți în modul de lucru, în calitatea pe care o livrează, în modul în care învață unii de la alții. Astfel, oamenii vor investi timp și efort pentru a perfecționa ”Cum-ul”. Unele echipe doar își vor îndeplini sarci-nile, altele vor excela la acesta.

Dar aici intervine partea interesantă. Cu cât o echipă agilă este mai matură, cu atât își va schimba focusul de pe definirea funționalităților pe care trebuie să le livreze (”Ce-ul”) și de pe modalitatea în care face aceasta într-un mod eficient (”Cum-ul”), pe

motivul pentru care trebuie să construiască aceste funcționalități, pe valoarea adusă în final Businessului (”De Ce-ul”). Pe scurt, o echipă matură va dori să cunoască mai mult nevoile Business-ului, va pune la încercare propunerile invalide, va da suport, se va axa pe a aduce valoare și nu pe a construi funcționalitate.

Dar de ce ar fi o echipă suprasolici-tată, care deja luptă pe mai multe fronturi, interesată să cunoască și ”De Ce-ul” și dedesubturile acestuia? Răspunsul este relativ simplu: cu cât pui la încercare moti-vul, cu atât te pui pe tine și pe clientul cu care lucrezi la încercare și cu atât dezvolți o relație mai strânsă cu acesta. Există o tehnică interesantă , Tehnica celor cinci ”De Ce” (5 Whys Technique), care a prins popularitate în domeniul IT pentru aflarea cauzei problemelor, dar care a început să fie utilizată și pentru a pune la încercare ade-văratele nevoi ale clientului. Prin această schimbare de perspectivă, echipa nu mai este considerată a se ocupa doar cu dezvol-tarea de soft, ci are un rol mult mai mare pentru că îndeplinește și pune la încercare nevoile clientului, este implicată proactiv în procesul decizional.

Un model similar poate fi întâlnit in Cercul de Aur al lui Simon Sinek, un model simplu dar puternic pentru lea-dership-ul inspirațional, care pune foarte mult accent pe rolul întrebării „De ce?” și modul în care, răspunzând la această întrebare, problemele pot fi abordate într-o manieră convențională sau într-o manieră exceptională.

O mentalitate agilă înseamnă mult mai mult decât a fi agil

Oricât de simplist sau contradictoriu ar suna, a avea o mentalitate agilă înseamnă mult mai mult decât a fi sau a te comporta agil. A fi agil înseamnă să ai un compor-tament agil, iar acesta este influențat de caracterul individului, de experiența aces-tuia în proiecte agile, de cum acționează și interacționează într-o echipă. Mentalitatea agilă nu se naște în indivizi. Ea apare mai degrabă din împărtășirea unor experiențe, opinii, practici, comportamente între echipe și are ca rezultat construirea unui ”inventar” de cunoștințe și experiențe. Cu alte cuvinte, nu poate exista o mentalitate agilă acolo unde nu au existat deja echipe agile.

O mentalitate agilă are impact la mai

multe nivele. La început echipele agile promovează un mediu agil care, evoluând, duce la cultivarea unei mentalități agile. Asemenea unui bulgăre de zăpadă, o men-talitate agilă clădește o companie agilă și asta duce la alte echipe agile ș.a.m.d.

Mentalitatea agilă este cea care promo-vează schimbări vizibile la toate nivelele unei companii și care susține scalabilitatea și dezvoltarea. Cu cât oamenii și echipele împărtășesc o viziune agilă comună, deci o mentalitate agilă, cu atât organizația este capabilă să facă față schimbării și să evolu-eze. Lumea IT în care trăim astăzi a devenit un sistem complex, haotic. Companiile nu sunt capabile să inoveze, să aducă valoare fără să evolueze și să se adapteze. A avea o mentalitate agilă înseamnă a avea o deschi-dere pentru schimbare și pentru inovație și de aceea viziunea pe care oamenii o au despre inovație este importantă. Un citat anonim spune că ”Inovația este abilitatea de a vedea schimbarea ca o oportunitate și nu ca o amenințare” pentru că prin inovație ne putem schimba pe noi și tot prin inovație avem puterea de a schimba lumea din jurul nostru.

management

26 nr. 5/2012 | www.todaysoftmag.ro

Joacă „Hard Choices” în fiecare sprint și rascumpără-ți datoriile!

Așadar, datorii peste tot! Trebuie să le plătim? Când trebuie să le plătim?

Dar ce relevanță au datoriile țărilor în povestea datoriei software? Sigur putem face o analogie, vorbim tot despre organizații mai mari sau mai mici, despre posibilitatea lor de a fi competitive sau nu, de puterea de a se dezvolta mai rapid sau mai greu, de a putea răspunde mai rapid sau mai greu la nevoile clienților lor.

Metodologiile de dezvoltare agile ne spun că poți să te adaptezi rapid la nevo-ile pieței daca ești agile. Dar ce se întâmplă dacă tu știi că ești agile dar din nevoia de a răspunde rapid mai bagi niște mizerie sub preș? De câte ori poți să faci asta? Dacă ești project manager de câte ori poți să spui ca spui că echipa tehnică nu a livrat la timp? Dacă esti dezvoltator de câte ori poti să reestimezi și să întârzii un task? Poți cere de fiecare dată să reimplementezi totul de la zero? Dacă ești inginer la testare de câte ori poți să spui că nu dai release-ul pentru că ai primit binarele ieri și nu ai avut timp să testezi? Daca ești manager de release de câte ori poți să spui că trebuia să dai rele-ase-ul ieri dar nu ai avut ok-ul de la echipa de QA? De unde vin toate aceste probleme?

Cred ca v-ați prins că datoria în software se rezumă la toate deciziile de a amâna sau chiar ignora activitați de valoare în dezvoltarea software. Există exprimări

care te duc cu gândul că echipa acumuleaza datorii:• Nu avem timp acum, dar vom aloca

timp mai tarziu,• Nu avem nevoie de asta acum, dar

o să facem când o să avem nevoie,• Pe unde am mai lucrat nu am facut

dintr-astea și treaba mergea bine,• Nu știm cum se face sau nu am mai

facut așa ceva,• Nu avem timp să facem asta acum,

dar daca se întampla ceva nasol o să găsim noi o solutie.

Iar dacă datoriile sunt extrem de mari pe alocuri vedem exprimări de genul “la mine merge”, “la noi nu se reproduce” sau ”trebuia să fie gata ieri”.

Este clar că pe termen scurt echipa nu are nici o problemă. Dar ce se întâmplă pe termen lung? Poti să ai probleme mari la un demo și atunci ai nevoie de unul sau mai multe sprint-uri în care să platești datoria tehnică. Poți să mai ai probleme mari la clienți și nu ai cum să creezi un fix rapid care să nu strice altceva. Oare nu cumva se poate întampla ca produsul sau serviciul la care lucrezi sa își piardă din clienti și pur și simplu să devină falimentar ca business?

Sunt absolut convins că unii din-tre cititorii acestui articol se asteaptă la metodologii, rețete, tool-uri, practici de dezvoltare software sau agile dar pentru că

Bun venit în era datoriilor! America are datorii de aproape 16 trilioane de dolari și dacă nu ai ajuns la New York în Times Square poți vedea această datorie direct online pe site-uri precum http://www.usdebtclock.org/. Nu mai este o surpriză

pentru nimeni că Europa e într-o criza a datoriilor iar țările care excelează la acest capi-tol sunt Grecia, Spania, Italia, Irlanda și Portugalia cu aproximativ 120 bilioane de euro împrumutate. În mod cert și Romania este afectată de această criză sau participă la ea prin diverse acțiuni politice sau economice.

management

Adrian [email protected]

Project Manager și Software Engineering Manager Bitdefender

IT-ist prin excelenţă, Adrian și-a construit o carieră urmând pașii clasici, pornind de la Junior Software Developer, fiind apoi Senior Software Developer, Team Leader iar, în prezent, Project Manager și Software Engineering Manager. Cu o experiență de 4 ani în management de proiect, Adrian deține o certificare PMI-ACP și două certificări SCRUM (Certified Scrum Master și Certified Scrum Product Owner) oferite de ScrumAlliance.org, de asemenea este pasionat de aplicarea metodologiilor Agile în proiecte și de instrumentele software care pot facilita implementarea lor în diverse companii.

management

27www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

totul depinde tine și de organizația pe care o transformi zilnic o sa vorbim un pic des-pre un joc de societate inventat de Software Engineering Institute (de ai nostri).

Jocul Hard Choices simulează ciclul de dezvoltare software cu ajutorul conceptelor precum incertitudinea, riscul, opțiunile și datoria tehnică. Din dorința de a deveni lideri de piață în dezvoltarea de software, jucătorii se întrec în a lansa produse de calitate. Până la finalul unui joc toți expe-rimentează implicațiile efortului investit în “a face treaba ca lumea”, pentru a câștiga avantaj competitv, dar și în prețul plătit pentru a apela la scurtături. Jucătorii pot apela sau chiar combina cele două strategii pentru a face față incertitudinii și acesta se aseamănă cu alegerea echipei de a folosi o anumită metodologie pentru dezvoltarea de software.

Jocul are câteva reguli simple pentru a fi jucat destul de usor, exact cum Scrum-ul sau Kanban-ul are foarte puține reguli. De asemenea tururile de masă pot fi asemănate cu sprint-urile sau iterațiile cu care echi-pele agile sunt deja obișnuite. Din regulile jocului observăm că nu contează doar cine termina primul, ci și numărul de puncte adunate pe parcursul jocului, pentru că fiecare unealtă adunată înseamnă un punct valoros care ajută la stabilirea clasamentu-lui final.

Cel mai interesant aspect din jocul Hard Choices este faptul că atunci când decizi să alegi o scurtătură vei fi penalizat până când îți platești datoria, similar cu sprint-urile pentru ”technical debt”. Cât de mult ne întârzie lipsa unit testelor? Cu cât suntem penalizați atunci când nu avem teste automate care să ne valideze un build? Cât plătim când întârziem livrarea softului sau a unor fixuri? Oare cât plătim atunci când clienții nu regăsesc aceeași experiență după o actualizare a soft-ului?

De asemenea, atunci când jucătorii au în mână o carte unealtă și ajung într-o casuță care conține o nouă unealtă pot s-o folosească imediat aruncând încă o dată cu zarul sau pot să strângă cartea pentru a acumula puncte finale. Această regulă este asemănătoare deciziilor luate în interiorul sprintului, de exemplu în cadrul retrospec-tivei, decizii luate pentru a îmbunătăți o anumită componentă sau un anumit pro-ces, îmbunătățire care se vede imediat în următorul sprint, poți să mai arunci o dată cu zarul, sau la final când ajunge produsul în piață, se termina jocul.

Pentru a explica mai bine ce înseamnă datoria software, câțiva ingineri au testat jocul folosind următoarele trei strategii:

1. jucătorul alege tot timpul scur-tătura ș i plătește tot jocul scăzându-se un punct la fiecare aruncare de zar,

2. jucatorul alege scurtătura dar plătește imediat stând o tură fară să joace,

3. jucatorul nu alege niciodata scurtătura.

Strategia 2 este cea câștigătoare, iar strategiile 1 și 3 sunt aproximativ la fel de eficiente pentru regulile simple ale acestui joc. Dar dacă am sta două ture sau sprint-uri pentru a ne plăti datoria? Dar dacă am fi penalizați cu două puncte la fiecare aruncare de zar? În mod cert strategiile 1 și 3 s-ar diferenția din punct de vedere al eficienței.

Totuși scopul jocului nu este să ajungi la final cât mai repede ci să aduni puncte, cum s-ar zice în agile ”livrezi valoare”. Contează cine ajunge la final primul,

câștigă mai multe puncte, dar contează și câte puncte reușești să aduni pe traseu din colecționarea uneltelor.

În concluzie, acumularea de datorii este strâns legată de amânarea unor deci-zii și de ignorarea unor practici care pot să aibă rezultate pe termen lung. Poate că este simplu să îți spui că nu te implici în echipă pentru că oricum vrei sa înveți altă tehno-logie sau să schimbi proiectul. Dar oare nu există riscul ca în alta parte sa gasești o datorie și mai mare? Ce faci dacă alte echipe sau companii nu te acceptă în echipă dacă nu ești deschis pentru a face pair pro-gramming sau Test Driven Development?

management

28 nr. 5/2012 | www.todaysoftmag.ro

echivalente cu jumătate din emisiile trans-portului aerian, consumul total de energie fiind estimat la aproape 2% din producția mondială de electricitate [Metha, 2007]. Din raportul Kalyvianaki [Kalyvianaki, 2009] aflăm că pentru fiecare 1.00$ (chel-tuieli de capital) cheltuit pentru achiziția de echipamente noi, se cheltuie încă 0.50$ pentru curent și răcire. Având în vedere că atât cererea de servicii, cât și prețul ener-giei electrice, sunt în creștere, menținerea consumului de energie și a costurilor afe-rente la un nivel cât mai scăzut este una din prioritățile industriei. O posibilă soluție este scoasă în evidență de studii asupra centrelor de dimensiuni mari (mii de ser-vere), care arată că rata de utilizare medie a resurselor computaționale este de maxim 6% [Kaplan, 2008]. Explicația provine de la concentrarea pe performanță în detrimen-tul consumului de energie în politicile de management al centrelor. Adaptarea aces-tor politici pentru reducerea consumului și aplicarea lor dinamică în condițiile unei variații foarte mari a cererii constituie o provocare ce presupune atât complexitate cât și costuri care nu sunt de obicei asumate de către manageri.

În aceste circumstanțe, viziunea noas-tră este să considerăm consumul de energie ca o informație de context relevantă și să

dezvoltăm un sistem adaptiv la context (Green Cloud Scheduler) capabil să gesti-oneze dinamic consumul de energie și să ia decizii de management și adaptare care încearcă tot timpul să minimizeze acest consum, fără pierderi semnificative de performanță.

Pentru început se impune o definire mai exactă a conceptului de “sistem adaptiv la context”. Acestă denumire este dată unei anumite clase de sisteme distribuite capa-bile să detecteze și să înțeleagă schimbările din mediul de execuție și să își adapteze comportamentul în consecință. Spre deo-sebire de sistemele tradiționale, care nu se folosesc de context pentru a le influența comportamentul, cele adaptive la context, folosesc datele din mediul de execuție, atât cele interne, cât și cele externe, pentru a înțelege și mai ales pentru a se adapta la schimbări, ele dispunând de mecanisme senzoriale pentru a percepe mediul, de raționament pentru a îl înțelege și de un set de acțiuni posibile pentru a se adapta în timp real.

Ideea principală din spatele Green Cloud Scheduler (un planificator ecolo-gic de resurse computaționale) este de a modela problema consumului ridicat de energie, ca o problemă de context și adap-tare, în care utilizarea resurselor din centrul

În ultimul timp, consumul de energie datorat proceselor de IT și centrelor de date și servicii, a crescut până la a deveni o adevărată provocare ecologică. Agenția de Protecție a Mediului din Statele Unite (U.S. Environmental Protection Agency [EPA]) a cuantificat acest consum, pentru anul 2006, la suma de 61 miliarde de kilowați-oră, ceea ce înseamnă un cost de peste 4,5 miliarde de dolari. În același raport, este prezentată o dublare a con-sumului de electricitate necesar centrelor de servicii și date în perioada 2006-2011 și în următorii ani se estimează o accelerare a acestei creșteri datorită adoptării paradigmei „cloud computing”. La nivel mondial, emisiile de CO2 asociate centrelor de date sunt

programare

Planificator Ecologic pentru OpenNebula

Ionuț Anghel, Ph. [email protected]

Asistent Doctor Inginer Departamentul CalculatoareFacultatea de Automatica si Calculatoare

Universitatea Tehnica din Cluj-Napoca

Tudor Cioară, Ph. [email protected]

Asistent Doctor Inginer Departamentul CalculatoareFacultatea de Automatica si Calculatoare

Universitatea Tehnica din Cluj-Napoca

29www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

de calcul este adaptată dinamic la variațiile nivelului de încărcare, astfel încât eficiența energetică să fie maximizată. În general, în centrele de servicii virtualizate, resursele computaționale sunt supradimensionate pentru a face față încărcării maxime, iar Green Cloud Scheduler va monitoriza schimbările în nivelul de încărcare și va lua măsuri de adaptare, cum ar fi: (i) acțiuni de configurare și consolidare a resurselor (ex. alocarea de resurse către VM (Mașina Virtuală), activarea VM), și (ii) acțiuni de management dinamic al energiei (ex. punerea unui server în hibernare sau tre-zirea la viață, etc.)

Green Cloud Scheduler respectă una din cele mai folosite arhitecturi în domeniul sistemelor adaptive la con-text: MAPE-K (Monitorizare, Analiză, Planificare, Execuție – Cunoștințe (eng. Knowledge) având în centrul său datele/informațiile/cunoștințele de context.

Faza de monitorizare este responsa-bilă cu colectarea informațiilor de context legate de consumul de energie și cerințele de performantă din întreg centrul de date și reprezentarea acestor date într-o formă uniformă și pretabilă procesării ulterioare folosind ontologii. Această abordare per-mite analiza automată a consumului de energie și inferarea de noi cunoștințe folo-sind tehnici de raționare.

Faza de analiză evaluează Service Center Greenness Level (Nivelul Ecologic al Centrului de Servicii) prin compa-rarea valorilor unui set de GPI/KPI (Green Performance Indicators/Key Performance Indicators - eng. Indicatori de Performanță Ecologici/Indicatori Cheie de Performanță) evaluate în faza de moni-torizare cu un set de valori de referință stabilite în faza de design a centrului de date. Acești indicatori sunt reprezentați în XML și convertiți în SWRL, pentru a permite evaluarea prin raționare, fiind clasificați după cum urmează: (i) indicatori

de nivel aplicație, cum ar fi: timpul de răs-puns și performanta, (ii) indicatori de nivel virtualizare, cum ar fi: alocarea VM CPU și memorie VM și (iii) indicatori de infra-structură, cum ar fi: MHz/Watt, Deployed Hardware Utilization Ratio (DH-UR – Rata de Utilizare a Hardware-ului), Power Usage Effectiveness (PUE – Eficiența Utilizării Puterii energetice). Dacă nivelul Service Centre Greenness Level este sub un prag predefinit și toți indicatorii sunt îndepliniți, considerăm centrul într-o stare verde din punct de vedere al consumului și nu este nevoie de acțiuni de adaptare. În caz contrar este inițiată o fază de pla-nificare și aceasta va lua deciziile necesare pentru selectarea celei mai bune acțiuni de adaptare care va aduce centrul într-o stare verde.

Faza de planificare are ca scop prin-cipal luarea automată a unei decizii, fără intervenție umană, privind secvența corectă de acțiuni de adaptare care tre-buie executată pentru a impune valorile minime ale GPI/KPI și a aduce centrul într-o stare verde. Procesul decizional are în centru său un proces de analiză “what-if ” implementat folosind tehnici specifice de învățare automată (eng. reinforcement learning). Acest proces construiește un arbore decizional prin simularea tuturor acțiunilor ce ar putea îmbunătății eficiența energetică a centrului (ex. pornirea sau migrarea unei mașini virtuale, pornirea/oprirea unui server fizic), iar apoi selec-tează secvența optimă folosind un sistem de penalizări/recompense.

Faza de execuție are ca scop execuția dinamică, în timp real, a acțiunilor deter-minate în faza de planificare. Un Modul de Acces la Infrastructură ii oferă Green Cloud Scheduler mijloacele necesare acce-sării resurselor hardware și software din centrul de date pentru a impune acțiunile din planul de adaptare. Acest modul (vezi Figura 2 - Infrastructure Access Module)

este format din: • CentOS 5.5 Linux sistemul de ope-

rare folosit de serverele din centrul de servicii. Implementarea Green Cloud Scheduler este generică, deci poate fi folosită cu orice altă distribuție de Linux. O acțiune adaptivă posibilă la nivelul siste-mului de operare fiind oprirea unui server, exemplificata în codul de mai jos, unde Global Control Loop (Bucla Globală de Control) execută codul necesar pentru realizarea acțiunii.

// connect through ssh to the target server // IP = host.getHostname() and issue a // shutdown command

String cmd = “/usr/bin/ssh” + host.getHostname() + “sudo /sbin/shutdown -h now”;Process proc = Runtime.getRuntime().exec(cmd);

// wait until the server does not respond to // ping anymorewaitUntilTargetIsOff(host.getHostname());

proc.getInputStream().close();proc.getOutputStream().close();proc.getErrorStream().close();proc.destroy();

• KVM (Ker nel -based Vir tual Machine) este un hypervisor (super-vizor) care are rol în virtualizarea resurselor hardware și se instalează peste CentOS. Principalele funcții folosite sunt cele de monitorizare și management ale mașinilor virtuale.

• OpenNebula este un middleware pentru managementul norilor (eng. clouds). A fost ales datorită popularității, dar Green Cloud Scheduler poate fi ușor adaptat ori-cărei alte platforme de management infrastructură. OpenNebula oferă funcționalități de management ale tuturor mașinilor virtuale din centru, cum ar fi: crearea, instala-rea, migrarea, etc. Middleware-ul OpenNebula implementează două tipuri diferite de migrare (vezi codul de mai jos): (i) migrare live (liveMigrate) – serverele migrează mașina virtuală fără a o opri și (ii) migrare off-line (migrate) – cu oprirea mașinii virtuale pe perioada copierii pe un server nou.

PhysicalHost destination;

// get a reference to an existing virtual // machine having the // OpenNebula ID = taskinfo.getID()VirtualMachine machine = new VirtualMachine(taskInfo.getId(), client);

// issue a live migration or an offline // migration depending on the configuration // of the GCLOneResponse response = (GeneralConfigrationManager. getVMMigrationMechanism().quals(„live”)) ? machine.liveMigrate(destination.getId()) : machine.migrate(destination.getId());

if (response.isError()) { throw new ServiceCenterAccessException(response.getErrorMessage());}

Figura 1. Arhitectura Green Cloud Scheduler

30 nr. 5/2012 | www.todaysoftmag.ro

programare

• Open SSH este folosit pentru comu-nicarea în rețea, atât cu serverele cât și cu mașinile virtuale.

• Wake on LAN este un instrument folosit pentru a porni un server folosind o conexiune la rețea. De exemplu comanda >wol server-MAC din codul de mai jos.

// GeneralConfigurationManager.// getNodesWakeUpMechanism() returns // „wakeonlan”(Ubuntu) or // „wol” (CentOS/Scientific Linux)String cmd = GeneralConfigurationManager. getNodesWakeUpMechanism() + „ „ + physicalHost.getMac();

//execute the wakeonlancommandProcess proc = Runtime.getRuntime().exec(cmd);

OutputStream outputStream = proc.getOutputStream();

InputStream stdin = proc.getInputStream();InputStreamReader isr = new InputStreamReader(stdin);

//log the wakeonlan outputBufferedReader br = new BufferedReader(isr);String line = br.readLine();

if (line != null) { GlobalLoopLogger.getLogger().debug(line);}//wait until server responds to pingGlobalLoopLogger.getLogger(). info(„Waiting for” + physicalHost.getHostname() + „ to respond to ping”);

waitUntilTargetIsAlive( physicalHost.getHostname());// wait until server responds to SSH // connection request needed because SSH is // used by OpenNebula to deploy/migrate // virtual machines

GlobalLoopLogger.getLogger().info( „Waiting for” + physicalHost.getHostname() + „ to respond to SSH”);waitUntilSSHAvailable( physicalHost.getHostname());

Pentru implementarea arhitecturii MAPE-K s-a folosit stiva de software prezentată în Figura 2. Pe scurt: s-a folosit JaDE (Java Agent DEvelopment

Framework) pentru agenții inteligenți ce ajută la luarea deciziilor în fazele MAPE; Java RMI (Java Remote Method Invocation) pentru comunicarea între module; Apache Log4J pentru logare; AspectJ permite monitorizarea codului în timpul rulării și îmbunătățește nivelul de detaliu în faza de monitorizare; Java WS (Java Web Services) pentru comunicarea gradului de încărcare; JAXB (Java Architecture for XML Binding) folosit pentru transmiterea parametrilor intre module.

Odată definită arhitectura de bază și implementarea unui prototip funcțional, echipa a cercetat și diferite metode de îmbunatățire a managementului resurse-lor prin folosirea unor algoritmi inspirați din biologie (un exemplu ar fi folosirea unei analogii între grupări de servere și formațiunile V ale păsărilor migratoare, pentru a determina când un server este considerat aglomerat, când poate accepta încărcare suplimentară și când poate fi oprit, nefiind folosit). Dar cel mai impor-tant pas a fost aplicarea practică a cercetării în cadrul a două proiecte:

1. Poiectul GAMES (Green Active Management of Energy in IT Service centers), proiect european în care un consorțiu de opt entități din mediul academic și industrie au aplicat cunoștințele acumulate în două implementări: HLRS în Stuttgart (Germania) și centru de servicii Engineering Pont Saint-Martin (Italia); obținându-se creșteri ale eficienței energetice cu până la 25-30%, fără scăderi ale

performanței sau calității serviciilor.2. Green Could Scheduler pentru

OpenNebula, este inițiativa prin care încercăm să diseminăm teh-nologia în cadrul comunității OpenSource și s-a materializat prin trimiterea modulului către OpenNebula Community Manager, i ar în urma unui Audit de performanță acesta a fost accep-tat și inclus în oferta OpenNebula Ecosystem, putând fi descărcat de la adresa http://opennebula.org/software:ecosystem:green_cloud_scheduler, instalat și folosit.

În încheiere am dori să prezentăm rezultate comparative între OpenNebula Scheduler și Green Cloud Scheduler. După cum se vede în cazul folosirii algoritmului Fit-First al Open Nebula consumul ener-getic este de 1032 Wh, pe când folosind Green Cloud Scheduler avem un consum de 871 Wh, rezultând o reducere a consu-mului de energie cu 15.6%.

Aceste rezultate confirmă faptul că prin folosirea unor strategii de alocare mai bună a resurselor se pot obține rezultate care să aibă un real impact asupra mediului și a costurilor energetice impuse de creșterea consumului de servicii IT, practic fără nici un fel de costuri suplimentare, doar insta-larea unui modul software. Suntem siguri ca prin relaxarea criteriilor de performanță și prin investigarea altor strategii de redu-cere a consumului, putem să împingem eficiența energetică și mai mult.

Figura 2. Stiva Green Cloud Scheduler si Infrastructure Access Module

Figura 3. Eficientizarea Consumului de Energie. Rezultate comparative

Bibliografie[EPA] U.S. Environmental Protection Agency - ENERGY STAR Program, Report to Congress on Server and Data Center Energy Efficiency - Public Law 109-431, 2007.

[Metha, 2007] V. Metha - A Holistic Solution to the IT Energy Crisis - 2007.

[Kalyvianaki, 2009] E. Kalyvianaki - Resource provisioning for virtualized server applications - University of Cambridge Tech. Report, Number 762, ISSN 1476-2986, 2009.

[Kaplan, 2008] J. M. Kaplan, W. Forrest and N. Kindler - Revolutionizing data center energy efficiency - McKinsey & Company, 2008.

31www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

Designul experienței utilizatorului și moduri de aplicare în dezvoltarea produsului

Design-ul înseamnă din ce în ce mai puțin rezolvarea problemelor și elimi-narea frustrărilor. Totul se învârte, din ce în ce mai mult, în jurul îmbunătățirii experienței utilizatorului. Acum nu mai e de ajuns utilizabilitatea. Design-ul trebuie să se integreze în viața oamenilor. Chiar trebuie să aducă fericire în viața oamenilor și să anticipeze nevoile lor.

UX-ul inc lude toate asp ec te le interacțiunilor dintre utilizatorul final și companie, servicii și produse. Un bun UX înseamnă satisfacerea nevoilor exacte ale clientului. Pentru a obține calitate înaltă, UX-ul trebuie să fie o îmbinare perfectă de mai multe servicii, inclusiv design-ul interfaței, industrial, de inginerie și marketing.

Unul din principalele scopuri ale oricărui bun designer este comunica-rea mesajului într-un mod care duce la o experiență bună pentru utilizator. Culoarea textului, aliniamentul paginii, imaginile, modelul de design – toate sunt parte a aces-tei comunicări, indicii care deseori rămân neobservate sau neexprimate, dar care au un rol decisiv în UX.

Aceasta poate include interacțiunile cu un software, o pagina web, un call center, o reclamă, un sticker pe calculatorul cuiva, o aplicație pe mobil, un cont Twitter, prin e-mail, poate chiar față în față. Suma totala a acestor interacțiuni alcătuiesc UX-ul .

Principiile UXPentru cei mai mulți oameni, schim-

barea înseamnă frică și stres și impune familiarizarea cu produsul, însă poate fi

și reconfortant. Ne permite să trăim și să functionăm cu o anumită ușurință care nu necesită gândire activă permanentă. Construirea unui produs de succes rareori se face copiind produsele altora. Produsele de succes se creează schimbând, în mod fundamental, percepția oamenilor des-pre ce le va satisfice nevoile și asigurând o tranziție ușoară către noul produs.

Experiențele bune sunt simple“Simplitatea este sofisticarea extremă” –

Leonardo da VinciCând produsul este atât de complet

încât nu mai este nimic de adăugat sau de înlăturat. Când lucrurile sunt ințelese per-fect și reprezentate de statutul și aspectul lor, să le privești înseamnă să le înțelegi și să le cunoști. Dacă oamenii pot ințelege și folosi ceva cu mică dificultate, atunci s-a creat ceva simplu. Dar simplitatea nu e ușor de creat, doar pare astfel.

Ciclu de viațăPe masură ce utilizatorii interacționează

cu produsul sau serviciul tău, ei trec printr-o serie de pași numită ciclu de viață . Ca orice alt ciclu de viață, ciclul de viață de uti-lizare are un început, un mijloc și un sfârșit.

Etapele ciclului de viață:• Primul contact – oamenii află despre

produs,• Prima utilizare – prima utilizare a

produsului și momentul în care uti-lizatorul reflectă asupra obligațiilor pe termen lung; este prima reală impresie despre produs,

• Utlizarea continuă – folosirea

Design-ul experienței utilizatorului și al interfeței (UX) se referă la un concept care plasează utilizatorul final în centrul eforturilor de design și de dezvol-tare, spre deosebire de sistem, de aplicațiile sale sau doar valoarea sa estetică .

Cerința pentru un UX exemplar este satisfacerea nevoilor exacte ale clientului. Eleganța și simplitatea conferite de designer garantează un bun grad de utilizare și convingere utilizatorului de a cumpăra. Unul din principalele scopuri ale oricărui bun designer este comunicarea mesajului într-un mod care duce la o experiența bună pentru utilizator. Prezentul articol oferă un insight în acest proces.

UIX

Sveatoslav [email protected]

User Experience and User interface Senior Designer

Designer și consultant inde-pendent din România, cu vastă experieță în UI, UX, Interaction design, Information design, Visual design, Web Design, Web 2.0 și Web development.

32 nr. 5/2012 | www.todaysoftmag.ro

regulată a produsului,• Utlizarea entuziasmată – utilizatorul

devine imersat în produs,• Moarte – oamenii încetează sa mai

folosească produsul.

ConversațieUX înseamnă, de fapt, un bun market-

ing. Înseamnă să cunoști piața și orientarea pieței și să faci un design corespunzător. Mai înseamnă și să colectezi feedback și să faci schimbările în funcție de orientarea pieței, îmbunătățind experiența elemente-lor pieței, luând în considerarea semnul de egal dintre utilizatori și piața. Utilizatorii înseamnă piața pentru care faci design.

UX-ul, ca și marketing-ul, creează un dialog cu utilizatorii, al cărui scop este învățarea și îmbunătățirea experienței lor.

InvisibilitateCând utilizatorul se bucură de un bun

UX, nu se gândește la munca depusă pentru a crea acel design. Un bun UX înseamnă că nimeni nu vorbește despre designeri.

ContextNu există un răspuns corect pentru o

problemă de design. Există doar răspunsuri bune, proaste și mai bune pentru situația actuală. Fiecare soluție potențială se află într-un context anume.

Pentru a obține un răspuns optim, tre-buie să știi contextul în care se află. Trebuie avut în vedere scopul și resursele necesare atingerii acestuia. Un designer trebuie să știe care sunt țelurile aplicației sau ale pro-blemei tratate, ce doresc utilizatorii, ce știu aceștia și conținutul.

SocialUn designer tinde să se gândească la ce

încearcă să obțină, ce a construit în trecut, și deci, în termeni de ce face sau ce ar trebui să facă. Aceasta duce la încercarea de a con-trola totul, de a ajusta caracteristici. Socialul se petrece în lume și utilizatorii nu te au pe tine sau produsul tău în minte, ci propri-ile experiențe și cei cu care le împărtășesc. Schimbă cadrul în care lucrezi.

Nu mai avem de-a face cu oameni ci cu vieți sociale. Trebuie să facem față atât comportamentului individual cât și mediului veșnic schimbător al cărui nuanțe influențează comportamentul.

Strategia UXStrategia de design e în serviciul

utilizatorului. Adevărata provocare este rezolvarea problemei umane. Înseamnă înțelegerea nevoilor și aspirațiilor lor și satisfacerea lor, deci servirea utilizatorului. Uneori, nevoile lor sunt de a fi suprinși și încântați, însă nu ne pot spune cum să îi surprindem sau să îi încântăm. Acest lucru e datoria designer-ului, de profesie creativi.

Designer-ul de UX trebuie să poată răs-punde clar la cinci întrebări pentru a crea un produs ce rezonează imediat cu clientul.

Pentru a dobândi această viziune și strategie, un expert UX trebuie inclus în proiect de la începutul acestuia, având o pozitie unică pentru a răspunde la aceste întrebări :

Ce problemă încercăm să rezolvăm?Înainte să începem construcția unui

produs, trebuie să identificăm problema pe care încercăm să o rezolvăm. Problema trebuie prezentată cât se poate de clar și concis. Odată formulată astfel, avem o lentilă prin care putem răspunde la restul întrebărilor, clarificând scopul și elaborând strategia.

Cine este clientul?Este una din cele mai importante între-

bări pentru fiecare produs nou. Fără a înțelege clar cine este publicul țintă, există riscul să construim un produs ce nu sati-sface sau nu se potrivește cu așteptările clientului. Cercetările legate de utilizatori, etnografia și personajul, sunt toate com-ponente ale instrumentelor UX care pot răspunde la această întrebare.

Cum putem îmbunătăți structura și soluțiile existente?

E foarte valoros să înțelegem cum au încercat alții să rezolve o problemă similară pentru a putea evita greșelile lor, pentru a identifica structurile eșuate sau care au nevoie de îmbunătățiri și pentru a identi-fica momentele călătoriei clientului care îl pot surpinde și încânta. Această întrebare ne-o vom pune de nenumărate ori în tim-pului procesului de design.

Când ar trebuie să începem să primim feedback de la utilizatori?

Devreme și des e răspunsul comun la această întrebare, însă nu e întotdeauna adevărat. Dacă îl prezentăm prea devreme, riscăm ca dezvoltarea produsului sa fie dirijată de utilizator. Dacă îl prezentăm prea târziu pierdem feedback valoros care ar putea evita excesul. Înțelegând cine sunt clienții țintă și cum se pot îmbunătăți soluțiile existente ne ajută la identificarea momentului în care se poate incorpora

feedback-ul în dezvoltarea produsului.De ce rezolvă produsul nostru

problema?După identificarea problemei pe care

încercăm sa o rezolvăm, cine este publicul țintă și unde se pot aduce îmbunătățiri, ar trebuie sa putem explica de ce soluția noastră e bună. Aceasta ar trebui să fie baza scopurilor pe termen scurt în cadrul unei strategii pe termen lung.

Cum pot informații le ajuta la înțelegerea produsului pe care î l construiești?

Există numeroase analize care pot fi folosite pentru a confirma presupuneri, decizii de design și pentru a clarifica modul în care produsul se potrivește pe piață. Tehnici precum: data mining, eye-tracking, testare A/B, user flow, cercetări etnografice, benchmarking și multe altele pot fi folosite pentru o mai bună înțelegere. Niciun detaliu nu e prea mic pentru a fi tes-tat. Copy, layout și interacțiune – în toate aceste cazuri, informații bune pot ajuta la înțelegerea rezultatelor și ajustarea lor.

Companiile care încep prin a răspunde la aceste întrebări și se implică în procesul de UX design au șanse mai bune de a crea produse viabile, longevive decât companiile care le construiesc fără aceste răspunsuri. În lumea mereu în creștere a start-up-uri-lor, cei care apreciază și aplică UX-ul de la început vor fi cei de succes.

Un instrument obiectiv pentru măsu-rare și analiză ajută să oferim clienților recomandări bazate pe fapte, și nu doar opinii și presupuneri. Metodologia prezen-tată în acesta articol va ajuta să :• Elimine preferințele personale

(subiectivitatea) cât de mult posibil,• Permită persoanelor de profesii dife-

rite (designer, developer, client) sa înțeleagă la fel produsul,

• Ofere clienților o prezentare faptică a beneficiilor și limitărilor produsu-lui lor,

• UX-ul este format din patru factori principali:

• Branding,• Gradul de utilizare,• Funcționalitate,• Conținut.

De unul singur, niciunul din acești factori nu oferă o bună experiență; totuși, împreună, acești factori constituie prin-cipalele ingrediente ale succesului unui produs.

Mai jos se pot găsi explicații pentru

UIXDesignul experienței utilizatorului și moduri de aplicare în

33www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

fiecare element și parametrii de bază folosiți într-un model de analiză.

BrandingBranding-ul include toate elementele

legate de estetică și design ale unui produs. Implică proiectarea mesajului și imagi-nii dorite pentru un produs. Moduri de a măsura branding-ul includ:• Impactul vizual al produsului

e în concordanță cu identitatea brand-ului.

• Grafica, elementele specifice și mul-timedia imbunătățesc experiența.

• Produsul este în conformitate cu imaginea percepută a brand-ului.

• Produsul se bazează pe mediu pen-tru a extinde brand-ul.

FuncționalitateFuncționalitatea include toate procesele

tehnice, „din spatele scenei”, livrarea de servicii interactive destinate utilizatorilor finali, atât publicul cât și administratorii. Moduri de a măsura funcționalitatea sunt:• Utilizatorul primește răspunsuri

rapide la întrebări.• Progresul unui task e comunicat

clar.

Grad de utilizareGradul de utilizare înseamnă ușurința

de utilizare a componentelor și feature-uri-lor produsului. Moduri de a măsura gradul de utilizare sunt :• Eficacitate: abilitatea utilizatorului

de a folosi cu succes un Website pentru a găsi informații și a înde-plini sarcini.

• Eficiența: abilitatea unui utilizator de a îndeplini sarcini rapid, ușor și fără frustrări.

• Satisfacție: cât de mult un utiliza-tor folosește Website-ul cu plăcere.

Se referă la frecvența și gravitatea erorilor, cât de des utilizatorul face greșeli în timp ce utilizează sistemul, cât de grave sunt aceste erori și cum reactionează utilizatorul la ele.

• Memorabilitate: dacă a folosit sis-temul înainte utilizatorul poate să iși amintească suficient de acea experiență pentru a-l utiliza în mod eficient data următoare sau trebuie să reînvețe totul de la început?

ConținutConținutul se referă la adevăratul

conținut al produsului (text, multimedia, imagini etc.) dar și structura sau arhitec-tura acestuia. E important modul în care informația și conținutul sunt structurate în moduri definite de nevoile utilizatoru-lui dar și de client. Moduri de a măsura conținutul includ:• Conținutul este structurat într-un

mod care facilitează atingerea sco-pului utilizatorului.

• Conținutul este conform nevoilor și scopurilor utilizatorului și clientului.

• Conținutul este comprehensiv în mai multe limbi.

Măsurarea eficacității design-ului este un lucru nou pentru mulți designeri. Și, într-adevăr, suntem la început și încă mai avem de învățat până să ajungem să o facem bine. Există mai multe motive pen-tru care design-ul nu se măsoară, inclusiv datorită faptului că nu s-a stabilit un sis-tem de evaluare comun, nefiind clar cum se măsoară experiența utilizatorului legat de un produs/serviciu și nu se poate sta-bili o metodologie. Niciunul din aceste lucruri nu e ușor: e nevoie de o întreagă cultură dedicată colectării de feedback și îmbunătățirea sa, abilitatea de a accesa date legate de utilizatori și website, dar și abili-tatea de a programa și porni o inițiativă de rectificare a unui feedback negativ.

Fiecare proiect are nevoie de anumite instrumente în funcție de provocarea pe care o are în față. Cele care pot ajuta cel mai mult în ceea ce privește claritatea datelor și creșterea productivității sunt :

Schițele sunt grafice trasate de mână care conțin idei de ecran sau grafice de explicații a celei mai importante probleme sau soluții. Sunt foarte importante înainte de formarea, explorarea sau realizarea ideilor. Schițele vor ajuta la clarificarea ele-mentelor necesare îndeplinirii scopurilor.

Wire-frames sunt grafice generate pe calculator ce ilustrează organizarea de conținut, feature-uri și funcționalitate. Prioritizarea elementelor de design și

determinarea planului general poate fi foarte haotică. Un wire-frame bine construit va evidenția piesele individuale și se va asi-gura că aparțin de pagina corespunzătoare.

Mock-ups sunt grafice bogate ce simu-lează aspectul și atmosfera proiectului pentru o mai bună înțelegere a impactu-lui vizual asupra brand-ului. Un mock-up poate prezenta adevărată impresie și poate comunica adevăratele sentimente și per-sonalitate ale unui proiect. Fără a construi cu adevărat site-ul (ceea e o mulțime de oameni fac), nu există altă metodă de a defini în mod concret cum ar trebui să arate produsul final.

Prototipurile HTML sunt versiuni parțial complete ale website-ului folosite pentru a înțelege cum vor interacționa paginile între ele dar și fluxul de la o zonă la alta. Interacțiunile mai complicate ale unor componente mai sofisticate nece-sită prototipuri funcționale pentru a le putea înțelege. Când există multe elemente mișcătoare și țeluri cu mai multe etape, prototipurile HTML sunt utile pentru a acoperi golurile dintr-un plan.

Pentru cei mai mulți dinte noi, majo-ritatea muncii înseamnă perfecționarea, actualizarea și îmbunătățirea sistemelor existente. Noile cadre de design apar cu scopul de a le face reutilizabile, design-uri elastice și ca un drum spre inovație. Pe măsură ce aplicațiile și produsele devin din ce în ce mai complexe, cu siguranță nu dorim să ne petrecem timpul reinventând roata. Dar aceste sisteme, cadre și „bune practici” ne pot împiedica să ieșim din tipar și să cream ceva cu totul nou.

ConcluziiTestarea gradului de utilizare e unul

dintre cele mai bune lucruri care se poate face pentru a înțelege dacă utilizatorii pot folosi produsul așa cum a fost menit.

Mulți oameni susțin că această testare este dificilă, neconcludentă și chiar o pier-dere de timp. Credem că multe din aceste noțiuni sunt consecințe ale neînțelegerii procesului sau cerințelor pentru testare. Da, testele cantitative, calitative și cele de dezvoltare comparativă pot fi copleșitoare. Adevărul e că ceva testare e mai bine decât deloc. Poate încă te gandești că acest lucru nu va funcționa pentru tine. Stilul „do-it-yourself ” pentru testarea gradului de utilizare a început să rezoneze cu designeri, ingineri și manageri de produs.

Poate ajuta la îmbunătățirea produ-sului, ceea ce va duce la clienți fericiți și satisfăcuți.

Figura 1. UX-ul este format din 4 ele-mente interdependente

34 nr. 5/2012 | www.todaysoftmag.ro

Codul sursă este javascript nativ, nu se folosește de alte librării javascript. Se integrează foarte bine cu ASP.NET și cu alte limbaje server-side. În pagina HTML trebuie să inserăm referința către librăria Knockout.

De ce Knockout?• Elegant dependency tracking - face

update la UI în mod automat ori de câte ori Data Model se schimbă.

• Folosește Declarative Bindings - cu o sintaxă specifică, Knockout ne permite să ne conectăm din UI la Data Model.

• Este extensibil – au apărut o serie de plugin-uri după release. Knockout are deja o comunitate activă bine formată.

DOM-ul poate fi foarte ușor manipulat cu JQuery, dar JQuery nu oferă o decuplare perfectă a funcționalității de UI. Rezultatul folosirii librăriei Knockout va fi un cod mult mai structurat. Knockout se folosește de patternul MVVM. Folosind Knockout putem renunța la event-handlerele masive, care se intersectau. În Knockout totul este declarativ.

Despre patternul MVVM (Model View ViewModel)

Patternul Model-View-ViewModel (MVVM) ne ajută la separarea nivelului de business de interfața grafică (UI). Această separare ne ajută la evitarea multor pro-bleme de development și de design, făcând

mai ușoare testarea și suportul aplicației. Istoric vorbind, MVVM se trage din

MVP (Model-View-Presenter). În acest pattern Modelul reprezintă efectiv datele din aplicație, View-ul reprezinta UI-ul, iar Presenter-ul face legătura dintre cele două. Practic Presenter-ul ține referințe atât către Modele, cât către View-uri.

Caracteristici ale lui MVVM:• Modelul reprezintă partea de date

din aplicație. Toate clasele de busi-ness (domain objects) fac parte din Model.

• Între View-uri și ViewModel-uri există o relație de unu la unu, fie-care View are propria instanță de ViewModel. Pentru a realiza o separare clară între logică și UI, funcționalitatea se implementează în ViewModel. ViewModel-ul ape-lează clasa de business, dacă este cazul.

• Decuplând total partea de UI de partea de logică, putem foarte ușor aplica Unit testing pe core. În cazul unei aplicații cu procese complexe, acest lucru este de o importanță crucială.

Dacă folosim ASP.NET / MVC,

Business Logic and Data va fi o clasă de tip controller care returnează JSON. Folosind rutarea MVC, fiecare funcție din controller are popriul ei URL, care poate fi ușor apelată din templateul razor (View).

Presentation Logic va fi o clasă javascript cu aceeași structură ca și clasa C#, iar logica UI va fi definită în tem-plateul Razor.

ViewModel-ul poate fi generat din JSON folosind

plugin-ul de knockout mapping.

Knockout este o librărie Javascript care ne ajută la crearea paginilor web „desktop like”, care au un data model clar stabilit și ne permite ca UI ul să fie perfect sincronizat cu data model. Knockout este un proiect open-source creat de Steve

Sanderson, programator la Microsoft. Este proiectul lui personal, nu este proprietatea companiei Microsoft. Codul sursă poate fi descărcat de pe GitHub, iar documentația relevantă, precum și ultimele notificări de pe siteul: http://www.knockoutjs.com

programare

Construirea interfețelor web dinamice

folosind MVVM și ASP.NET

Figura 1. - Paternul MVVM

Csaba Porkolá[email protected]

Software developer @ Macademian

35www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

var viewModel = ko.mapping.fromJS(jsonString);

<div id=”PatientForm”> <p><label>Firstname: </label> <span data-bind=”text: firstName”> </span></p> <p><label>Lastname: </label> <span data-bind=”text: lastName”> </span></p>

<p><label>Fullname: </label> <span data-bind=”text: fullName”> </span></p></div>

<script language=”javascript” type=”text/javascript”> var viewModel = { firstName: ko.observable(‘John’), lastName: ko.observable(‘Harlid’), fullName: ko.computed(function() { return this.firstName() + “ “ + this.lastName(); }, this) }

ko.applyBindings(viewModel, $(‘#PatientForm’));</script>

În exemplul de mai sus avem un viewModel definit și un HTML template. Legătura dintre viewModel și un DOM ele-ment se realizează cu applyBindings. Dacă nu specificăm DOM element și scriem doar ko.applyBindings(viewModel), legă-tura se va face cu HTML body.

Proprietățile firstName și lastName sunt observables, adică sunt supervizate. Dacă se schimbă valoarea lor, UI-ul va fi updatat. FullName e o proprietate de tip computed și va fi updatat dacă firstName sau lastName se va schimba. Un observa-ble este o funcție care ne returnează the latestValue dacă este apelată fără vreun parametru.

Putem superviza și obiecte de tip array utilizând observableArrays, Knockout punându-ne la dispoziție o gamă largă de funcții pentru manipularea lor, cum ar fi. push, remove, removeAll.

Legăturile (bindings) predefinite de knockout dintre care nu le vom enumera decât pe cele importante se împart în trei categorii:1. Legături care controlează textul și

aparența sunt:a. Visible binding: Ascunde sau arată

un element DOM <div data-bind=”visible: isVisible”>

(isVisible este un observable și returnează boolean)

b. Text binding: Setează proprie-tatea innerText al unui element DOM <span data-bind=”text: myMessage”> (myMessage este un observable și returnează string)

c. Html binding: Setează proprietatea innerHTML al unui element DOM <span data-bind=”text: myHtml”> (myHtml este un observable și retur-nează string)

d. Css binding: Adaugă sau șterge o clasă sau mai multe clase CSS aso-ciate elementului DOM în funcție de o condiție; errorCount este un observable și returnează int

<span data-bind=”css: {errorWarning: errorCount() > 0, hide: errorCount () ==0}”>

Style binding: Adaugă sau șterge un style CSS asociat elementului DOM în funcție de o condiție; errorCount este un observable și returnează int<span data-bind=” css: { color: errorCount() > 0 ? ‚red’ : black’}”>

e. Attr binding: Adaugă sau șterge atribute asociate unui element DOM <a data-bind=”attr: { href: url, title: details }”>

2. Control flow bindings:a. Foreach binding: Ne permite

afișarea unui template de mai multe ori bazat pe un observableArray

<ul data-bind=”foreach: students”> $index<li data-bind=”text: name”></ul>

În exemplul de mai sus am afișat nume-le studenților. $index afișează indexul curent al elementului iterat. $parent este obiectul părinte.b. If binding: Cu ajutorul lui putem

adăuga sau șterge elemente DOM pe baza unui observable de tip boo-lean. Dacă displayMessage e false atunci div-ul va fi scos din DOM. În loc de un observable de tip boo-lean putem folosi expresii logice complexe.

<div data-bind=”if: displayMessage”> Here is a message.</div>

3. Event bindings:a. Click binding: Va executa o funcție

definită în viewModel în caz de click

<button data-bind=”click: doSomething”>

b. Event binding: Permite atașarea unui event javascript la obiectul DOM.

<div data-bind=”event: { mouseover: enableDetails, mouseout: disableDetails }”>

Legături virtualeLegăturile de tip “Control flow” pot fi

aplicate și elementelor DOM virtuale.<ul><li class=”heading”>My heading</li> <!-- ko foreach: items --> <li data-bind=”text: $data”> </li> <!-- /ko --></ul>

Custom Mappings Nu suntem limitați numai la

folosirea legăturilor definite în librăria Knockout, ci putem crea unele noi. Primul pas în procesul de creare este înregistra-rea legăturii ca o subproprietate a clasei ko.bindingHandlers:

Parametrii de intrare celor două funcții coincid:ko.bindingHandlers.legaturaNoua = { init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {// Va fi apelată atunci când legătura se // realizează cu un element DOM. },

update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {// Va fi apelată atunci când legătura se // realizează cu elementul DOM sau// când se schimbă valoarea unui observable // în model }};

• element – elementul DOM cu care se realizează legătura

• valueAccessor – este o funcție Javascript, care returnează propri-etatea din model, care e invocat în legătura curentă

• allBindingsAccessor – este o funcție Javascript, care returnează toate proprietățile legate de elementul DOM.

• viewModel – obiectul viewModel, care a fost folosit la inițializarea legăturii în funcția applyBindings.

• bindingContext – obiectul care conține datele de context al legătu-rii. Conține proprietăți ca $parent, $root, care pointează spre o legă-tură părinte, precum la legătura de rădăcină.

Concluzii Knockout este o librărie compactă.

Merită folosită în cazul paginilor mai complexe, care au multe apeluri Ajax. Un dezavantaj al librăriei ar fi viteza în cazul paginilor supra-aglomerate cu legături. Durata procesului de generare a legăturilor unei pagini are aproximativ 30 de secțiuni legate de câte un observableArray poate fi de o secundă și astfel sunt cazuri când tranziția devine vizibilă.

Figura 2. - Clasele KO

36 nr. 5/2012 | www.todaysoftmag.ro

Circula vorba prin ”târg” dacă nu ești pe Facebook, nu exiști?! Prima dată când am auzit această expresie mi s-a părut amuzantă și de neluat în serios. Facebook a ajuns la 1mld. de utilizatori și acum pot spune că afirmația de mai sus nu este deloc de neglijat. Totul se întâmplă pe Facebook, de la campanii de recrutare, la recrutarea efectivă a candidaților. Facebook-ul are avantajele și dezavantajele lui. Înainte de orice este considerat ca fiind un spațiu per-sonal, însă orice apariție pe internet este publică și devine vizibilă și pentru alții. Sunt recruiteri care utilizează Facebook-ul ca o sursă de identificare a candidaților. Mi s-a întamplat să găsesc informații actuali-zate în comparație cu clasicele site-uri de recrutare. Pe Facebook toată lumea are profilul actualizat: de la compania unde lucrează la activitățile extra pe care le întreprinde.

Scopul nu este de a scrie un articol des-pre cum se utilizează Facebook-ul pentru că mai mult ca sigur fiecare din noi știe acest lucru, dar cu siguranță mulți din-tre noi nu luăm în considerare impactul pe care îl poate avea ceea ce se publică pe profilul personal, motiv pentru care voi lua fiecare secțiune care mi se pare relevantă în procesul de recrutare și o voi analiza din perspectiva ”Așa îmi doresc să văd un profil”.

Secțiunea About you – o consider ca fiind extrem de relevantă în culegerea unor informații cât mai relevante despre candi-datul cu care urmează să interacționez. Cu cât este mai detaliată, cu atât poate consti-tui un mare plus. Ce fel de informații caut eu ca și recruiter? Cred că cel mai simplu mi-ar fi să exemplific: o persoană care are ca motto ”Nothing is impossible”, mă gândesc că este o persoană orientată spre obținerea rezultatelor și identificarea soluțiilor indife-rent de circumstanțele în care se află.

Secțiunea Work and Education vă recomand să o lăsați vizibilă publicului larg. Marele plus este adus de actualizarea constantă a acesteia și dacă este posibil atașați un link către companiile în care lucrați sau ați lucrat.

Secțiunea Contact Info – aici rămâne la latidutinea fiecăruia dacă dorește să facă publice datele de contact. Pentru mine ca recruiter situația ideală ar fi cea în care să găsesc public numărul de telefon , dar fiind vorba de confidențialitate, fie-care poate alege ce să publice și ce nu. În schimb vă recomand să puneți link-uri către proiecte personale sau profesionale în care ați fost implicați, site-uri personale sau blog-uri.

Toată lumea a auzit, cu siguranță, despre ”Social Networks”, sau mai pe românește despre ”Rețele de socializare online”. Nenumărate articole pe această temă au fost scrise, care mai de care mai detaliate despre istoricul conceptului, despre plusuri

și minusuri, despre confidențialitatea informației. Acest articol are ca scop indentificarea impactului pe care prezența pe aceste site-uri de socializare îl are asupra procesului de recrutare. ”Rețele de socializare” sunt destul de numeroase, dar pentru că spațiul este limitat, articolul va face referire doar la două dintre ele: Facebook și LinkedIn.

HR

Social networks

Andreea Pâ[email protected]

Recruiter în cadrul Endava și trainer specializat în dezvoltarea abilităților si competenețelor de leadership, comunicare și muncă în echipă

37www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

Secțiunea Events – participați activ la

evenimente pe Facebook și conectați-vă cu persoane din domeniul vostru de activitate, cu persoane care au interese comune și folosiți aceste conexiuni pentru proiectele pe care le dezvoltați, pentru că am ajuns într-un moment în care cu cât cunoști mai multe persoane cu atât vizibi-litatea ta este mai ridicată în mediul în care interacționezi.

Și acum intrăm în subiectul mult con-troversat ”Pictures”. Am întâlnit deseori întrebarea: ”Ce fel de poze îmi recomanzi să public pe Facebook?”. Mereu la această întrebare am răspuns foarte personal, iar din punctul meu de vedere orice fel de poze în care nu ești pus în situații stân-jenitoare sunt potrivite. Cu siguranță în contexul prieteni, poate produce bună dispoziției, dar pentru un recruiter nu este cel mai plăcut lucru pe care dorește să îl vadă. Dar, pe de altă parte am primit contra-argumente la această opinie a mea, repet strict personală, referitoare la faptul că la urma urmei este alegerea mea dacă mă uit la pozele respective sau nu.

Am început cu Facebook-ul, deoarece este cea mai utilizată ”rețea de socializare” și care din punct de vedere profesional încă nu este utilizat la potențial maxim. Facebook-ul va deveni cu siguranță sursa care poate oferi cele mai importante informații despre noi ca persoane. Sunt sigură că există companii care ar plăti sume mari de bani pentru a avea acces la informații cât mai detaliate. Așa că vă recomand să vă gândiți de două ori ce publicați pe această rețea de socializare.

Un alt site de socializare pe care aș vrea să îl prezint este LinkedIn-ul, care este o rețea mult mai profesională și care nu este utilizat astfel încât să aducă bene-ficii maxime. Mai mult decât atât, există nenumărate persoane care încă nu au auzit despre acest site. Avantajele LinkedIn sunt și mai mari decât cele pe care Facebook-ul le oferă, pentru că site-ul în sine este struc-turat mai profesionist. Secțiunele pe care LinkedIn-ul le are permit crearea unui CV online mult mai relevant decât cel care apare pe Facebook. Statistic vorbind, LinkedIn-ul a ajuns deja la peste 100 mil de utilizatori. Ca scop, LinkedIn-ul poate fi utilizat pentru găsirea unui job sau pentru a conecta persoane din lumea business-ului, prin facilitatea de a crea evenimente și de a le promova online.

Secțiunea Profile – oferă posibilitatea creării unui CV electronic. • În categoria Summary, așa cum îi

spune și titlul, se notează ce consi-deri că este relevant, fie un rezumat al evoluției în carieră, fie punctele forte sau cunoștințele pe care con-sideri că le ai, fie rezultatele pe care le-ai avut de-a lungul carierei. Mai simplu spus, ce te face pe tine unic în comparație cu ceilalți utilizatori care doresc același job ca și tine.

• Specialties recomand să te lauzi cu ce știi să faci cel mai bine.

• Experience descrie cât mai clar și concis responsabilitățile pe care le-ai avut la locurile de muncă, inclusiv voluntariat. Plusul pe care îl aduce LinkedIn-ul este că pentru fiecare post, poți solicita o recomandare. Un profil care are un CV bun și are și recomandări, este imposibil să nu atragă atenția recruterilor sau head-hunterilor. Te sfătuiesc să ceri recomandări și fă-le cât mai diversificate pentru a avea un feedback din toate mediile

în care ai interacționat.• Education se referă la educația for-

mală.Sugestie: pentru cei care au deja facultate și master să nu mai menționeze liceu în profil. Ultima parte din această secțiune se referă la interesele pe care fiecare le are și la diferite informații personale.

Secțiunea Groups – recomand să te înscrii în grupurile de interes pentru tine. Scopul lor este mult mai bine definit

decât pe Facebook, deoarece poți avea a c c e s l a r e s u r s e sau la opi-nii pe baza discuțiilor p e c a r e l e p o ț i in iț ia ca m e m b r u al grupu-lu i , p oț i afla păre-rea unor specialiști în dome-

niu într-un mod foarte simplu și util. Secțiunea Jobs – cu utilitate maximă

pentru cei interesați de un job nou, este una dintre resursele cele mai importante pe care LinkedIn-ul le pune la dispoziția utilizatorilor.

Recitind articolul mi-am dat seama că nu am făcut o observație chiar relevantă. În momentul în care dorești să adaugi o persoană în listă, personalizează invitația prin a explica motivele pentru care vrei să devină parte a rețelei tale profesionale.

Impactul crescut al celor două ”rețele de socializare” este demonstrat prin creșterea numărului utilizatorilor. Comparativ cu anul 2011, LinkedIn-ul a crescut cu 4 mil de utilizatori, iar Facebook-ul cu 300.000.000 de utiliza-tori. Cele două rețele oferă numeroase oportunități atât în ceea ce privește găsirea unui job nou, dar în același timp facilitează interacțiunea în lumea business-ului.

Pentru cei care încă nu au un profil pe LinkedIn, recomand să nu mai amânați si să-l faceți, iar ceilalți care aveți unul, dar nu este complet, vă sfătuiesc să începeți să îl actualizați și să deveniți din ce în ce mai vizibili.

Succes!

38 nr. 5/2012 | www.todaysoftmag.ro

C o r e D a t a A P I p o a t e f i descompus în următoarele trei com-ponente: Persistent Store Coordinator (NSPersistentStoreCoordinator), Managed Object Model (NSManagedObjectModel) ș i M a n a g e d O b j e c t C o n t e x t (NSManagedObjectContext). Toate cele trei părți lucrează împreună pentru sto-carea/încărcarea obiectelor persistente (NSManagedObject).

Managed Object Model (NSManagedOb-jectModel)

Încapsulează schema bazei de date, care conține entități și relațiile dintre ele descriind graful de obiecte. Îl putem crea cu ajutorul instrumentului vizual oferit de Xcode (care va fi compilat într-o resursă binară) sau chiar din cod. De obicei, nu e nevoie să-l accesăm după ce stiva Core Data (Core Data stack) a fost inițializată, dar pentru scenarii complexe – deoarece conține descrierea tuturor entităților care compun modelul – este posibil să-l folosim pentru a interoga dinamic modelul pentru descoperire/afișare.

Managed Object Context (NSManage-dObjectContext)

Instanța NSManagedObjectContext este obiectul pe care îl accesăm atunci când vrem să salvăm, citim, creăm și să ștergem obiecte persistente. Este pe ultimul nivel al

stivei, și interacționează cu obiectele per-sistente prin acest context. (Orice obiect persistent creat trebuie sa fie legat de un context). De asemenea, nu este thread-safe, prin urmare, toate thread-urile cu care vrem să accesăm obiecte persistente trebuie să aibă un context separat. Este important să se țină cont de faptul că, la fel ca și în cazul UI-ului, instanțele de NSManagedObjectContext trebui să fie accesate doar de pe threadul pe care au fost create.

Persistent Store CoordinatorSe află la baza stivei Core Data și este

responsabil pentru serializarea/deseriali-zarea obiectelor persistente. Locul în care se depozitează datele (Persistent Store) poate fi pe disc sau în memorie. Trei tipuri de depozite sunt incluse în Core Data API: SQLite, XML și binar. Toate acestea pot fi serializate pe disc sau în memorie (sto-carea în memorie fiind doar un storage temporar).

XML și binar sunt depozite atomice (întregul fișier de date este rescris la fie-care salvare). Deși depozitele atomice au avantajele lor, ele nu sunt scalabile. Un alt dezavantaj al lor este faptul că sunt încărcate complet în memorie, astfel încât amprenta pe memorie este mult mai mare în cazul lor decât în cazul SQLite. Totuși pentru un set mic de date pot reprezenta varianta optima.

SQLite este o bibliotecă de software care implementează un motor de bază de dată SQL de sine stătător, fără server, pre-configurat, tranzacțională. Este cel mai des

Core Data este un graf de obiecte și un framework pentru persistența datelor oferit de Apple. Este un framework relativ mic, dar foarte robust, oferă soluții pentru multe probleme generale și se potrivește perfect cu Cocoa si alte API-uri furni-

zate de Apple. (În MVC pattern ține loc de model).

programare

Core Data – În spatele scenei

Zoltán, Pap-Dá[email protected]

Software Engineer @ Macadamian

39www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

folosit motor de bază de date SQL. Prin folosirea unei baze de date relaționale ca depozit persistent, nu avem nevoie de încărcarea tuturor datelor în memorie. De asemenea baza de date poate fi scalată la dimensiuni foarte mari. SQLite în sine a fost testat cu seturi de date măsurate în terabytes. Datele de pe disc sunt organizate eficient, doar datele pe care le folosim la un moment dat, sunt încărcate în memo-rie. Pentru că avem o bază de date în loc de un fișier plaintext, avem acces la mai multe opțiuni pentru creșterea performanței. Putem controla, de asemenea, modul în care obiectele sunt încărcate în memorie.

Pentru cele mai multe scenarii Core Data oferă un acces transparent, dar pen-tru a scrie aplicații scalabile, eficiente, bazate pe Core Data, trebuie să cunoaștem ce se petrece în spate scenei, altfel riscăm să ne confruntăm cu situații neplăcute.

FaultingFaulting este una dintre cele mai

sensibile subiecte legate de Core Data. Se desfășoară în mod transparent, prin urmare aplicațiile simple pot fi dezvoltate fără a cunoaște detaliile de funcționare. În ceea ce urmează, voi folosi un exemplu simplu, pentru demonstrarea impactului asupra performanței.

Să considerăm un model nou, în care creăm o singură entitate (Person) cu trei atribute (age, gender, name), fără nici o relație. Luăm în considerare o bază de date,

cu 5000 de instanțe ale acestui obiect.

Dorim să iterăm prin toate obiectele și să verificăm un

atribut al obiectului (Desigur, putem face mult mai eficient, cu definirea unui pre-dicat, însă dorim să ne asigurăm că toate obiectele vor fi încărcate în memorie)

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@”Person” inManagedObjectContext:context];

[fetchRequest setEntity:entity];

NSArray * result = [context executeFetchRequest: fetchRequest error:&error];//timp de execuție 0.552 s

for (Person * person in result) { if ([person.age intValue] < 25) value++;}//timp de execuție 0.083s

Se observă că putem inspecta toate obiectele într-un timp decent. Acum vrem să extindem modelul cu o altă entitate, precum și o relație între cele două entități.

Creăm o entitate nouă: Car cu trei atri-bute (engine, manualTransmission, name), precum și o relație între Person și enitatea Car.

Folosim o bază de date, care conține 5000 de obiecte Person, și fiecare persoană are un obiect Car (în total avem 10000 obiecte). De asemenea, dorim să extindem următoarea interogare, iterăm în conti-nuare toate obiectele Person, dar acum inspectăm un atribut din obiectului referit de relația între cele două entiați.

NSFetchRequest *fetchRequest= [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@”Person” inManagedObjectContext:context];

[fetchRequest setEntity:entity];

NSArray *result=[context executeFetchRequest:fetchRequest error:&error];//timp de execuție 0.351 secunde

for (Person * person in result) { if (person.car.manualTransmission) { value += [person.age intValue]; }}//timp de execuție 21.201 secunde

După executarea codului, putem obser va o degradare accentuată a performanței. Dar ce s-a întâmplat? Dacă verificăm un obiect Person înainte de par-curgere, în debugger, putem observa că este marcat ca și Fault. Înainte de accesare obiectul nu se află încărcat în memorie!

În continuare vom studia procesul de încărcare a datelor.

Încărcarea (Fetching) obiectelorPentru a optimiza utilizarea memo-

riei, Core Data folosește lazy loading la încărcarea datelor. „Fetching” este terme-nul folosit pentru a adresa pașii care sunt urmați pentru a crea un obiect în memorie pornind de la conținutul din storage (câm-purile obiectului sunt stocate în tabelele bazei de date relaționale). Când folosim SQLite ca storage, după executarea unei cereri, este foarte posibil ca un obiect pe care-l credem în memorie, este de fapt pe disc și trebuie să fie încărcat în memorie ulterior. În mod similar, obiectele despre care credem că sunt gata pregătite, de fapt se află încă într-un cache.

Atunci când este executat un NSFetchRequest, vom prelua o listă de NSManagedObject, dar în spatele acestor obiecte, în memorie, vom avea doar obiecte substituente (Faulting objects). Singurul atribut care este încărcat în memorie este NSManagedObjectID. Deasmenea obiec-tele au o proprietate (isFault) cu ajutorul

căreia se poate verifica dacă obiectul este încărcat în memorie, sau nu. Când acce-săm primul atribut, dar în memorie avem doar un placeholder, o notificare este inițiată (Fault is fired) pentru a încărca obiectul în intregime în memorie. Să ana-lizăm mai detaliat.

A. După executarea requestului (NSFetchRequest), vom avea o listă de faulted NSManagedObject,

B. Când începem să iterăm peste lista rezultată și accesăm un atribut al primului obiect, un mesaj va fi tri-mis automat nivelelor inferioare Core Data,

C. Core Data verifică conținutul cache-ului intern. Pentru că obiectul respective nu face parte din cache, Core Data apelează la repository, pentru deserializarea obiectu-lui,

D. Cu un singur acces la baza de date, toate obiectele din lista respectivă sunt încărcate în cache. Când pri-mul obiect este încărcat în memorie, conținutul lui se poate accesa. (isFa-ult va fi NO pentru primul, si YES pentru următoarele obiecte),

E. Iterarea peste listă va fi rapidă, deoa-rece obiectele se află în cache.

Deoarece accesul multiplu la baza de date pentru a încărca lista obiect cu obiect, nu este eficient, datele sunt încărcate în bucăți (chunks). Acest comportament poate fi reglat prin setarea proprietății FetchBatchSize al NSFetchRequest -lui. Valoarea implicită este 0, ceea ce cores-punde la ∞ (toate elementele listei vor fi încărcate în cache la prima accesare). În

40 nr. 5/2012 | www.todaysoftmag.ro

programareCore Data – În spatele scenei

cazul în care lista rezultat are multe ele-mente, am putea lua în calcul modificarea acestei valori, care va duce la un consum mai mic de memorie, pentru început, însă vor fi mai multe accesări ale bazei de date fizice.

Prin urmare, trebuie să considerăm fiecare caz în parte, atunci când vrem să schimbăm acest comportament implicit. De asemenea, putem opri acest comporta-ment prin

înainte de a executa query-ul. Astfel după executarea request-ului toate câmpu-rile obiectelor vor fi în cache.

Prin introducerea Faulting, Core Data încearcă să optimizeze consumul de memorie, astfel că pănă la prima accesare obiectele nu sunt încărcate în memorie. Trebuie să observăm, că nu toate propri-etatile și metodele din NSManagedObject cauzează trimiterea notificării de încărcare a datelor. Există o listă lungă de metode din NSManagedObject care nu cauzează porni-rea procedurii de încărcare a obiectelor: isEqual:, hash, superclass, class, self, zone, isProxy, isKindOfClass:, isMemberOfClass:, conformsToProtocol:, respondsToSelector:, retain, release, autorelease, retainCount, description, managedObjectContext, entity, objectID, isInserted, isUpdated, isDeleted, isFault

Grafuri de obiecte Primul exemplu a fost bazat pe entitați

simple fără utilizarea relațiilor. Următorul pas de extindere a structurii de date este introducerea relațiilor între entități. Acest pas poate avea un impact semnificativ asu-pra performanței unei aplicații Core Data.

În al doilea exemplu, putem observa degradarea performanței. Motivul pentru aceasta este faptul că relațiile sunt accesate și încărcate una câte una. În primul caz, accesarea primului element Persoana din lista, rezultă încărcarea tuturor celor 5000 de obiecte în cache printr-un singur acces la disk, în cazul al doilea când accesăm obiectul referință Car, Core Data încarcă în cache doar obiectul respectiv. Prin urmare, în al doilea caz în total 5001 de accese la disc vor fi folosite, comparativ cu primul caz în care toate datele sunt aduse în cache printr-un singur acces la disc. 5001 com-parativ cu 1. Acesta este motivul pentru ruinarea performanței.

Soluția pentru această problemă este

„Pre-Fetching” - anticiparea nevoilor vii-toare, pentru a evita încărcarea obiectelor prin accesări separate la disc. Acest lucru poate fi realizat doar enumerând relațiile, pe care le vom folosi pentru obiectele aduse. Astfel Core Data va ști dacă obiec-tele respective vor fi folosite și va asigura un acces optim la ele.NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@”Person” inManagedObjectContext:context];

[fetchRequest setEntity:entity];

[fetchRequest setRelationshipKeyPathsForPrefetching: [NSArray arrayWithObject:@”car”]];

NSArray * result = [context executeFetchRequest:fetchRequest error:&error];//timp de execuție 4.006 secunde

for (Person * person in result) { if (person.car.manualTransmission) { value += [person.age intValue]; }}//timp de execuție 0.974 secunde

Acest truc rezolvă problema noastră pentru moment, dar tehnica este destul de fragilă, pentru că trebuie să păstrăm codul sincronizat cu modelul, deoarece avem o relație hardcodată. Cănd modificăm relațiile din model, trebuie să propagăm modificările și în cod, altfel riscăm să ajungem la accesul ineficient pe care l-am subliniat anterior.

ConcluziiDupă cum am văzut, încărcarea

obiectelor cu accesări independente este una dintre cele mai comune cauze pen-tru performanțele slabe ale aplicațiilor Core Data. Mecanismul de „Faulting” este o sabie cu două tăișuri, care poate aduce îmbunătățiri mari pentru viteza si performanța aplicațiilor sau poate trage în jos performanța foarte mult. Trebuie să cunoaștem acest comportament al framework-ului Core Data și trebuie să păstrăm un echilibru între numărul de accesări de disc și consumul de memorie, și să aducem numai datele de care avem nevoie și numai la momentul potrivit. De asemenea e important să creăm schema modelului nostru ținând cont de aceste proprietăți.

Atunci când încărcăm datele, în cazul în care aducem prea puțin, aplicația va părea blocată, din cauza numărului mare de accese la disc. Pe de altă parte, dacă vom încărca cantitatea prea mare de date în memorie, vom avea acces rapid la datele noastre încărcate, dar vom avea probleme de memorie scăzută pe device-uri (să nu

uităm că iPad2 are o memorie internă de 512MB). De asemenea, trebuie să fim conștienți de faptul că, neavând virtualizare de memorie în iOS, Core Data încearcă să reducă consumul din memorie prin elimi-narea datelor nefolosite pe parcurs, astfel eliberând obiecte din cache atunci când acestea nu sunt folosite. Acest lucru ar putea cauza un acces suplimentar la disc chiar pentru obiectele care au fost anterior în memorie și au fost accesate.

Pentru îmbunătățirea performanței putem folosi următoarele:• Pre-inițializarea cache-ului (Cache

waming up). Putem preîncărca datele în cache pentru a fi siguri că datele vor fi disponibile, atunci când va fi nevoie de ele. Atunci când pornește aplicația, într-un thread separat pornim încărcarea datelor, care în mod sigur vor fi folosite în momentele ulterioare. Practic timpul de încărcare îl mutăm în faza de inițializare. În acest caz, nu contează dacă folosim mai multe thread-uri, deoarece toate operațiunile vor fi direcționate către NSPersistentCoordinator, care are un cache unic.

• Optimizarea accesului la disc . Având în vedere că accesul la disc este mult mai lent decât accesul la memorie, putem reduce numărul de accese la disc pentru a optimiza încărcarea datelor. Am văzut cum putem optimiza accesul la disc prin cunoașterea modului de încărcare a datelor. Aceeași problemă ar putea fi extins și la salvarea datelor. Este mult mai eficient a salva în bucăți mai mari în loc de a salva obiect cu obiect. Ștergerea obiectelor este, de asemenea, un subiect sensibil, care necesită o atenție specială. Chiar dacă ștergem un singur obiect, acest lucru ar putea implica eliminarea mai multor obiecte în cascadă dato-rită relațiilor dintre obiecte.

41www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

5 practici Java pe care le folosesc

Implementarea metodelor equals, hashCode și toString moștenite din java.lang.Object

Toate cele trei metode sunt parte din java.lang.Object din versiunea JDK 1.0. Mai jos este o listă a beneficilor folosirii acestor metode:

Object#equals(Object obj): determină dacă obiectul curent este egal cu obiectul trimis ca parametru. Implementarea lui Object#equals verifică doar dacă referințele celor două obiecte sunt egale (this == obj), dar această verificare nu este întodeuana suficientă. De obicei, o implementare com-pletă a lui equals verifică:

a. Dacă (obj == null) returnează false;b. Dacă (this == obj) returnează true;c. Dacă ( !getClass() .equals(obj.

getClass()) returnează false;d. Se execută un type cast a lui obj la

tipul lui this;e. Se verifică egalitatea attributelor lui

this și obj și în funcție de aceasta se returnează true sau false.

Suprascrierea lui equals este benefică dacă egalitatea stării obiectelor este impor-tantă pentru un program să ruleze corect De exemplu, obiectele sunt parte ale unor colecții și trebuie să fie găsite în cazul unor operații de citire. Altă situație este legată de scrierea testelor automate, unde, de obicei, se verifică egalitatea obiectelor ca parte a validării unui test.

Object#hashCode este altă metodă care poate fi folositoare în situații similare cu

Object#equals. Contractul general al lui hashCode este:

a. Equals este suprascrisă,b. Dacă două obiecte sunt egale, ele vor

genera același hash cod,c. Calcularea hash codului se va face

folosind aceleași atribute folosite pentru verificarea egalității,

d. Dacă nu se schimbă starea unui obiect, apeluri ale metodei hashCode trebuie să returneze aceeași valoare; totuși acest lucru nu este valabil pentru diferite rulări ale aplicației.

Colecțiile și mapele de tip hash sunt implemetate folosind structuri bazate pe hash (“buckets”). O implementare impro-prie a hash codului, ar putea produce rezultate neașteptate in cazul operațiilor de citire asupra colecților și mapelor hash (căutarea in structura greșită de hash). Din cauza punctului d). de deasupra, codul client poate să nu găsească un obiect dacă starea obiectului a fost schimbată între timp (și această stare este folosită în deter-minarea egalității). Cea mai bună cale pentru evitarea unor astfel de situații este folosirea obiectelor imutabile (starea lor nu se va schimba pe durata vieții lor). De asemenea, dacă obiectele sunt imutabile, implementarea hashCode va putea folosi tehnici de caching pentru o eventuală imbunătățire a performanței (hash codul trebuie să fie același dacă starea obiectului nu se schimbă).

De câte ori ne-am uitat la niște

Articolul prezintă cinci practici Java pe care le folosesc în scrierea codului meu. Este interesant că lucrurile simple îți fac viața de developer (și a colegilor) mai ușoară. Lista de mai jos nu este un top, doar ilustrează lucruri pe care le consider

folositoare.

programare

Tavi [email protected]

Development lead @ Nokia

42 nr. 5/2012 | www.todaysoftmag.ro

programare

loguri și am văzut ceva de genul: “value is: Car@29edc073”? Da, foarte ener-vant și nefolositor și totul pentru că Object#toString() nu a fost suprascrisă în clasa respectivă. Această metodă este foarte folositoare când vrem să logăm sta-rea obiectelor. Dacă logul ar arăta ceva de genul: “value is: Car[type=BMW,number of doors=5,isAllWheelDrive=false]” ar avea sens mai mult decât exemplul ante-rior. O sugestie în apelarea lui toString ar fi să nu se apeleze explicit în concatenarea cu alte stringuri: “value is “ + car, în locul “value is “ + car.toString(), deoarece, în acest context, “car” este oricum evaluat folosind toString() (ca urmare a conca-tenării cu un string) și am putea evita un NullPointerException, dacă “car” este null.

Pentru cele trei metode, Apache Commons Lang 3 (http://commons.apa-che.org/lang/) pune la dispoziție utilități care fac viața developerilor mai ușoară. Vezi https://github.com/tavibolog/TodaySoftMag/blob/master/src/main/java/com/todaysoftmag/examples/object-methods/Car.java și testul asociat.

Evitarea comenzilor imbricateÎn general, îmi place să scriu code

simplu si ușor de înteles. Bineînțeles, acest lucru nu se întâmplă întotdeauna. Ca o regulă de bază, prefer să ies dintr-o metodă/flow cât mai repede posibil. Făcând asta, se limitează complexitatea de a citi comenzi imbricate. Tehnicile de realizare a acestei ieșiri bruște dintr-un flow implică folosirea comenzilor: return, break, continue sau throw. În opinia mea, folosind:If (a == null) {return;} // și apoi continua flowul aplicație pe o urm

este preferabil:If (a != null) {//fă ceva} // și apoi continuă flowul între paranteze

O modalitate de a impune această practică este limitarea numărului de carac-tere pe o linie la 120 în IDE-ul pe care îl folosești.

Vezi https://github.com/tavibolog/TodaySoftMag/blob/master/src/main/java/com/todaysoftmag/examples/nested/Utility.java pentru două versiuni ale aceleiași metode, una folosind comenzi imbricate și celaltă încercând să le evite. Apoi alege-o pe cea care arată mai simplu.

Verifică validitatea parametrilor unei metode

Nimănui nu î i p l ace c a NPE (NullPointerException) să apară in stack-trace-ul codului său. Nici mie. Iată câteva tehnici de a evita acest lucru:

a. Folosește JavaDoc pentru docu-mentarea parametrilor de intrare. Problema ar fi că majoritatea deve-loperilor nu citesc JavaDoc-ul.

/** @throws NullPointerException in case argument is null */

b. Folosește assert-uri. Acestea sunt comenzi care permit developerilor să verifice anumite presupuneri asupra codului care se execută. Deci folosirea assert-urilor nu este pentru utilizatori. Când un assert eșuează, de obicei librăria care conține assert-ul are un bug. Cele mai commune cazuri de folosire ale asert-urilor sunt legate de para-digma “design-by-contract”:

• Pre-condiții: Verifică ce trebuie să fie adevărat când o metodă este apelată. Aceasta poate fi o soluție pentru metodele private, dar nu și pentru cele publice, pentru că aplicația poate rula și făra ca assert-urile să fie active și, dea-semenea, aserturile aruncă doar AssertionError si nu o excepție specifică., Deci metodele publice ar trebui să verifice validitatea parametrilor. Totuși, metodele private pot folosi assert-uri îna-inte de a executa orice operație.

private void divide(int a, int b) {

assert (b != 0);…..}

• Post-condiții: verifică ce trebuie să fie true înainte de terminarea unei metode. Aici, assert-urile sunt premise și pentru metodele publice pentru că anumite pro-bleme apărute pot fi rezolvate în codul client (de exemplu, obiec-tul account care este null mai jos)

private Account createAccount() { Account account = null;// create the account…assert (account != null);return account;}

• Invarianți ai unei clase: verifică ceea ce trebuie să fie adevărat tot timpul pe durata de viață a unui obiect. În această situație, orice contructor sau metodă publică trebuie să apeleze invariantul

înainte de a se termina, pentru a se asigura că starea obiectului este consistentă relativ la invariant.

Public class Account {String name = null;private boolean checkNameForNull() { // class invariant return name != null;}public Account(String name) {… assert checkNameForNull();}}

De reținut că nu este nici un mecanism de recuperare dintr-un assert, pentru că scopul asset-urilor este de a ajuta scrierea de cod testabil și de a proteja împotriva unor execuții care pot corupe starea aplicației.

Implicit, assert-urile nu sunt active. Pentru activare, se poate folosi:

java –ea MyClaasssaujava –enableassertions MyClass

c. Verificarea validității parametrilor de intrare și aruncarea de excepții după cum este necesar. Dacă codul se poate recupera dintr-o stare generate de intrări invalide, atunci ar trebui să folosești “checked exception”, dacă nu ar trebui să folosești “un-checked exception”. Vezi aici mai multe detalii des-pre folosirea excepțiilor: http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html. De obicei, constructorii nu pot instanția obiectele adecvat în cazul intrărilor invalide, așa că prefer să arunc IllegalArgumentException. De asemenea, este o practică bună se specificăm aruncarea de excepții în JavaDoc.

Vezi https://github.com/tavibolog/TodaySoftMag/blob/master/src/main/java/com/todaysoftmag/examples/check/Dog.java și testul asociat.

NOTA: Verificarea validității parame-trilor de intrare poate fi problematică în așa numita “fereastră de vulnerabilitate” În perioada dintre verificarea parametru-lui și atribuirea parametrului, alt thread ar putea modifica valoarea parametrului de intrare făcând verificarea parametrilor nefolositoare. Pentru evitarea unor astfel de situații, verificarea validității ar putea fi făcută pe operandul din stânga al unei atribuiri, după ce atribuirea s-a făcut.

5 practici Java pe care le folosesc

43www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINEHR

Evită zgomotul inutil

Este întotdeauna bine să îți menții codul cât mai curat. Uni developeri pot avea intenții bune în a urma cele mai bune practice, dar rezultatul muncii lor nu aduce întotdeuna beneficii, doar zgomot inutil.

Comentariile sunt folositoare doar dacă spun mai mult decât codul în sine. Dacă codul este foarte clar, atunci comentariile de mai jos nu prea au valoare:

a. /** seteaza persoana */public void setPerson(Person p){}

b. …// citește fișierul

readFile(new File(“…”));

…Ca regulă, mai bine îți denumești vari-

abilele și metodele cât mai clar cu putință pentru a evita comentarii zgomotoase. De asemenea, să nu uităm că și comentariile trebuie menținute în caz de refactorizare a codului, ceea ce înseamna din nou lucru în plus.

Următorul topic de discutat ar fi folosi-rea lui this. Aceasta are sens dacă:

a. Este folosit pentru apelarea unul constructor în cadrul unui alt con-structor pentru a evita duplicarea de cod de inițializare

public Person(String name, int age)

{this(name);}

b. Când numele unui atribut este iden-tic cu numele unui parametru

public setPerson(Person person){this. person = person;}

În alte cazuri, folosirea lui this nu aduce prea mare valoare. Mai jos sunt câteva contra-exemple:System.out.println(this.name);

System.out.println( this.COUNT_OF_MESSAGES);

Ultimul topic de discutat în acest capi-tol ar fi folosirea lui final. Acesta are sens dacă o variabilă va fi folosită într-o clasă inner sau dacă developerul vrea să atragă atenția că variabila respective nu ar trebui re-inițializată. Am folosit primul caz des-tul de des, în timp ce al doilea caz are sens

în special când se definește o constantă, dar nu ar trebui folosit din abundență în alte circumstanțe decât dacă este absolut necesar. public int add(final int a, final int b) { final int c = a + b; return c;}

Metoda de mai sus este corectă, dar ar fi mai simplu să o scriem ca mai jos:

public int add(int a, int b) { return a + b;}

Ai grijă să îți cureți resursele folosite

Este important ca resursele unei aplicații să fie bine administrate. În caz con-trar, aplicația poate avea un comportament neașteptat și eventual să necesite restar-turi. Una dintre cele mai clasice greșeli făcute de developeri este aceea de a uita să închidă stream-urile pe care le-au deschis. O secvență a folosirii unui stream ar fi:

a. Deschide stream,b. Lucrează cu streamul de date,c. Închide streamul.

Ultimul pas trebuie să se execute nea-părat chiar dacă apar excepții în aplicație. Până la Java 6, folosirea finally ne ajuta să fim siguri că un stream se închide întot-deauna. Iată cum ar arăta de obicei codul:

FileInputStream fis = null;try { fis = new FileInputStream(new File(„README”)); // Lucrează cu streamul aici} catch(IOException ioexp) {// administrează eventuale excepții} finally {// asigură-te că streamul se închideif (fis != null) { fis.close(); }}

Ce se poate întâmpla aici este că blocul finally să arunce o excepție și codul trebuie să o prindă, ceea ce înseamnă cod aditional care trebuie scris și menținut și care are o tendință repetitivă.

Începând cu Java 7, syntax lui try a fost extinsă pentru a defini scopul pentru strea-murile folosite, numit try-with-statements:try (FileInputStream fis = new FileInputStream(new File(„README”))) { //lucrează cu streamul aici}

Aceasta înseamnă că la sfârșitul blo-cului try, resursele care implementează

interfața AutoCloseable vor fi automat închise. Se pot chiar specifica mai multe resurse pe aceeași linie. Pentru a suporta acest concept nou, o mulțime de clase din JDK implementează începând cu Java 7 interfață AutoCloseable, incluzând pache-tele: java.io.*, java.nio.*, java.net.*, etc. De asemenea codul generat de compilator știe să administreze resurse nule.

Vezi https://github.com/tavibolog/TodaySoftMag/blob/master/src/main/java/com/todaysoftmag/examples/resour-ces/ResourceCleaner.java și testul asociat pentru a ilustra ambele situații (închiderea stream-urilor – incluzând un exemplu cu JDK 1.7 – și lipsa închiderii stream-uri-lor). În special pe sistemele Linux/Unix, neînchiderea streamurilor generează “FileNotFoundException” cu mesajul “too many open files” după ce numarul de stream-uri deschise depășește limita sistemului.

Un alt concept interesant în Java 7 este legat de administrarea excepțiilor mascate. Mascarea unei excepții este situația în care o excepție o maschează pe alta și nu este legată de situația în care codul client înca-drează o excepție venită de la un API de nivel jos. Dar în cazul în care o excepție este aruncată în blocul try și altă exceptie este aruncată in blocul finally, iar codul client va observa doar exceptia din blocul finally. Java 7 administrează automat această situație (în cazuri specifice se poate folosi Throwable.addSuppress(...)), mașina virtu-ală suprimând excepția din finally pentru a se administra excepția din try.

Este recomandat să lăsăm compilatorul să genereze codul de administrare pentru cazul de mascare a excepțiilor, pentru că va adauga codul minimal, iar developerul poate să se focuseze pe logica aplicației.

Alte situații care se află în aceeași cate-gorie de curățare a resurselor sunt:• Eșuarea închiderii conexiunilor la

bazele de date,• Eșuarea închiderii sockeților.

NOTA: Exemplele de cod au fost testate folosind Ubuntu 12.04, rulând open JDK 7 și Maven 3.

44 nr. 5/2012 | www.todaysoftmag.ro

void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e){ if (closing) { return; }

Skeleton first = GetFirstSkeleton(e);

if (first == null) { return; }

ContainerSkeleton.Children.Clear();Dictionary<JointType, Joint> jointsDictionary = new Dictionary<JointType, Joint>();

foreach (Joint joint in first.Joints) jointsDictionary.Add(joint.JointType, getScaledJoint(joint, e));

drawJoints(jointsDictionary);drawBones(jointsDictionary);}

Odată ce am primit un Frame de la Kinect, verificăm mai întâi daca este nul, iar apoi extragem încheieturile din primul schelet descoperit și le reținem într-un dicționar.

void drawJoints(Dictionary<JointType, Joint> jointsDictionary){ foreach (KeyValuePair<JointType, Joint> joint in jointsDictionary) { drawJointEllipse(30, Brushes.LightGreen, joint.Value); }}

private void drawJointEllipse(int diameter, Brush color, Joint joint){ Ellipse el = new Ellipse(); el.Width = diameter; el.Height = diameter; el.Fill = color;

Canvas.SetLeft(el, joint.Position.X - diameter / 2); Canvas.SetTop(el, joint.Position.Y - diameter / 2);

main.ContainerSkeleton.Children.Add(el); el.Cursor = Cursors.Hand;}

Metoda drawJointEllipse desenează câte o încheietură din corpul utilizatorului în ele-mentul de tip Canvas, ContainerSkeleton. Fiecare încheietură este reprezentată grafic de o elipsă.

void drawBones(Dictionary<JointType, Joint> jointsDictionary){Brush brush = new SolidColorBrush(Colors.LightGray);

ContainerSkeleton.Children.Add(getBodySegment(new PointCollection() { new Point(jointsDictionary[JointType.ShoulderCenter].Position.X, jointsDictionary[JointType.ShoulderCenter].Position.Y), new Point(jointsDictionary[JointType.Head].Position.X,

În numerele precedente, am introdus o secvență de cod cu rol în inițializarea Kinect-ului și am construit o scurtă aplicație de tip Hello World. În cele ce urmează, vom continua dezvoltarea aplicației printr-o funcționalitate nouă: afișarea scheletului

întreg al utilizatorului.

programare

Microsoft Kinect - Ghid de programare Partea a II-a – Afișarea

scheletului întreg al utilizatorului

Echipa [email protected]

45www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

jointsDictionary[JointType.Head].Position.Y) }, brush, 9));

ContainerSkeleton.Children.Add(getBodySegment(new PointCollection() { new Point(jointsDictionary[JointType.Shoulder-Center].Position.X, jointsDictionary[JointType.ShoulderCenter].Position.Y), new Point(jointsDictionary[JointType.ShoulderLeft].Position.X, jointsDictionary[JointType.ShoulderLeft].Position.Y), new Point(jointsDictionary[JointType.ElbowLeft].Position.X, jointsDictionary[JointType.ElbowLeft].Position.Y), new Point(jointsDictionary[JointType.WristLeft].Position.X, jointsDictionary[JointType.WristLeft].Position.Y), new Point(jointsDictionary[JointType.HandLeft].Position.X, jointsDictionary[JointType.HandLeft].Position.Y)}, brush, 9));

ContainerSkeleton.Children.Add(getBodySegment(new PointCollection() { new Point(jointsDictionary[JointType.ShoulderCenter].Position.X, jointsDictionary[JointType.ShoulderCenter].Position.Y), new Point(jointsDictionary[JointType.ShoulderRight].Position.X, jointsDictionary[JointType.ShoulderRight].Position.Y), new Point(jointsDictionary[JointType.ElbowRight].Position.X, jointsDictionary[JointType.ElbowRight].Position.Y), new Point(jointsDictionary[JointType.WristRight].Position.X, jointsDictionary[JointType.WristRight].Position.Y), new Point(jointsDictionary[JointType.HandRight].Position.X, jointsDictionary[JointType.HandRight].Position.Y)}, brush, 9));

ContainerSkeleton.Children.Add(getBodySegment(new PointCollection() { new Point(jointsDictionary[JointType.ShoulderCenter].Position.X, jointsDictionary[JointType.ShoulderCenter].Position.Y), new Point(jointsDictionary[JointType.Spine].Position.X, jointsDictionary[JointType.Spine].Position.Y), new Point(jointsDictionary[JointType.HipCenter].Position.X, jointsDictionary[JointType.HipCenter].Position.Y)}, brush, 9));

ContainerSkeleton.Children.Add(getBodySegment(new PointCollection() { new Point(jointsDictionary[JointType.HipCenter].Position.X, jointsDictionary[JointType.HipCenter].Position.Y), new Point(jointsDictionary[JointType.HipLeft].Position.X, jointsDictionary[JointType.HipLeft].Position.Y), new Point(jointsDictionary[JointType.KneeLeft].Position.X, jointsDictionary[JointType.KneeLeft].Position.Y), new Point(jointsDictionary[JointType.AnkleLeft].Position.X, jointsDictionary[JointType.AnkleLeft].Position.Y), new Point(jointsDictionary[JointType.FootLeft].Position.X, jointsDictionary[JointType.FootLeft].Position.Y)}, brush, 9));

ContainerSkeleton.Children.Add(getBodySegment(new PointCollection() { new Point(jointsDictionary[JointType.HipCenter].Position.X, jointsDictionary[JointType.HipCenter].Position.Y), new Point(jointsDictionary[JointType.HipRight].Position.X, jointsDictionary[JointType.HipRight].Position.Y), new Point(jointsDictionary[JointType.KneeRight].Position.X, jointsDictionary[JointType.KneeRight].Position.Y), new Point(jointsDictionary[JointType.AnkleRight].Position.X, jointsDictionary[JointType.AnkleRight].Position.Y), new Point(jointsDictionary[JointType.FootRight].Position.X, jointsDictionary[JointType.FootRight].Position.Y)}, brush, 9)); }

Metoda drawBones trasează un segment pentru fiecare dintre oasele cele mai importante din scheletul utilizatorului. Segmentele sunt adăugate în containerul ce conține și elipsele reprezentând încheieturile identificate anterior.private Polyline getBodySegment(PointCollection points, Brush brush, int thickness){Polyline polyline = new Polyline();polyline.Points = points;polyline.Stroke = brush;polyline.StrokeThickness = thickness;return polyline;}

private Joint getScaledJoint(Joint joint, AllFramesReadyEventArgs e){var posX = (float)GetCameraPoint(joint, e).X;var posY = (float)GetCameraPoint(joint, e).Y;

joint.Position = new Microsoft.Kinect.SkeletonPoint{ X = posX, Y = posY, Z = joint.Position.Z};

return joint;}

Un mod de a afișa încheieturile pe ecran ar fi prin folosirea metodei ScaleTo. Totuși, ScaleTo tinde să deformeze corpul utiliza-torului, astfel încât acesta să ocupe întreg spațiul disponibil pe display. Pentru a păstra proporțiile anatomice, vom converti manual coordonatele fiecărei încheieturi din sistemul metric în pixeli, prin intermediul funcției GetCameraPoint.

Point GetCameraPoint(Joint joint, AllFramesReadyEventArgs e){

using (DepthImageFrame depth = e.OpenDepthImageFrame()) { if (depth == null || sensor == null) { return new Point(0, 0); }

DepthImagePoint jointDepthPoint = depth.MapFromSkeletonPoint(joint.Position);

ColorImagePoint jointColorPoint = depth.MapToColorImagePoint(jointDepthPoint.X, jointDepthPoint.Y, ColorImageFormat.RgbResolution640x480Fps30); return new Point((int)(ContainerSkeleton.ActualWidth * jointColorPoint.X / 640.0), (int)(ContainerSkeleton.ActualHeight * jointColorPoint.Y / 480)); }

}

ConcluziiAfișarea scheletui complet e utilă în special pentru debugging (putem afla cu ușurință cât de precis sunt poziționate încheieturile

pe corpul utilizatorului), sau pentru unele aplicații grafice sau jocuri.

46 nr. 5/2012 | www.todaysoftmag.ro

Se dă un scenariu simplu: student sau proaspăt absolvent se angajează pe o poziție de “Software Testing Engineer”, generic denumit QA. În primele zile se familia-rizează cu compania, colegii, aplicația pe care urmează să o testeze. Mai mult, i se sugerează să studieze pentru certificarea de ISTQB Foundation Level, pentru o mai bună înțelegere a procesului de testare. Conștiincios, QA-ul nostru învață și în final obține diploma de certificare pentru primul nivel de testare software.

La un moment dat unele concepte sunt uitate, că doar suntem oameni, și apelează la prietenul Google pentru a reîmprospăta memoria. Inevitabil găsește pentru același concept, mai multe definiții, apropiate ca explicație, dar cu mici diferențe interpreta-bile (e.g “Test Automation”). Întrebarea ce urmează: Care e definiția cea mai potrivită, există acel “single source of truth” la care visăm ?

Da, s-ar putea să fie puțini cei care își aleg ca metodă de documentare stu-diile sau articolele stiințifice publicate pe această temă și majoritatea va opta pentru o căutare rapidă pe internet. Voi incerca, în exemplul ce urmează, să vă arăt că tes-tarea automată e mai mult decât rulare de teste, iar structura unui proces automat e muncă laborioasă ce implică mulți factori, nu doar ce găsim la o simplă căutare pe net. ISTQB e o certificare recunoscută la nivel mondial, dar totuși nu e singura. Nu toată lumea acordă o importanță majoră acestui tip de certificare și totuși un QA și un cer-cetator în domeniul testării software, pot vorbi aceeași limbă.

Testarea software tinde să fie o știință exactă, o știință studiată și bine definită. E un domeniu în care un concept primește o definiție în urma unui proces de evaluare și feedback, laborios și exercitat între per-soane academice, pe baza unor date reale.

Să dăm un exemplu concret: la o sim-plă cautare pe Google: “Test Automation”, accesați articolul din Wikipedia1, unde veți găsi următoarea definiție:

“In software testing, test automation is the use of special software (separate from the software being tested) to control the execution of tests, the comparison of actual outcomes to predicted outcomes, the setting up of test preconditions, and other test con-trol and test reporting functions. Commonly, test automation involves automating a manual process already in place that uses a formalized testing process.”

În schimb, dacă veți căuta același con-cept în studii și articole de cercetare, veți da peste principiul Parasuraman2, care definește testarea automată de forma:

“We propose that automation can be applied to four broad classes of functions: a) information acquisition; b) information analysis; c) decision and action selection; and d) action implementation. Within each of these types, automation can be applied across a continuum of levels from low to high, i.e., from fully manual to fully auto-matic.[…] We therefore use a definition that emphasizes human-machine compa-rison and define automation as a device or system that accomplishes (partially or fully) a function that was previously, or conceiva-bly could be, carried out (partially or fully) by a human operator [8].”

Se poate observa ca varianta Wikipedia se referă doar la partea de rulare a sce-nariilor de test, care, din perspectiva principiului academic, e doar un nivel intermediar unde automatizarea completă e definită prin lipsa oricărei intervenții umane. Pe o scală de la 1 la 10 (1- sistemul nu oferă deloc asistență, toate deciziile și acțiunile sunt umane; 10 – sistemul decide tot, acționează autonom, ignoră intervenția umană) Testarea Automată așa cum am invățat-o eu în primele zile de QA, se află la nivelul 5, nivel ce presupune doar execuția testelor, orice altă decizie fiind luată de om (definirea datelor de test, selecția testelor, analiza rezultatelor, etc).

Există o multitudine de modele de automatizare, care implică mai mult sau mai puțin intervenția umană, exemplul

oferit este doar un punct de pornire pentru o înțelegere mai bună a ce-și doreste fie-care echipă în momentul în care folosește testarea automată. În final, un proces efi-cient și de succes al automatizării software se rezumă la factori gen productivitate/costuri/calitate.

În concluzie, aș vrea doar să menționez, că fiecare își alege documentația și sursele de informare de unde crede de cuviință, fie online, fie offline, în final e irelevant. Ce este relevant e informatia cu care rămîne și acuratețea acelei informații. Testarea software, în special cea automată nu face parte din categoria artă creativă unde fie-care poate să vină cu o definiție proprie a ce inseamnă automatizare sau testare sau orice al termen. Și că tot vorbim de artă, automatizarea poate să devină o artă, în măsura în care procesele folosite, bine definite și demonstrate științific, vor aduce admirația oamenilor din domeniul software și nu numai.

Bibliografie

1. http://en.wikipedia.org/wiki/Test_automation

2. Raja Parasuraman, Thomas B. Sheridan, Fellow, IEEE, and Christopher D. Wickens – “A Model for Types and Levels of Human Interaction with Automation” in IEEE transactions on systems, man, and cybernetics—part a: systems and humans, vol. 30, no. 3, may 2000

Domeniul testării software a devenit din ce în ce mai dinamic, noi metode de testare sunt introduse, multe concepte redefinite sau reinventate. Celebra sintagmă “oricine poate să testeze” incepe să fie din ce în ce mai greu de confirmat, datorită nivelului tehnic ridicat și al tehnologiilor folosite în dezvoltarea aplicațiilor.

Testarea ca știință exactă

testare

Andrei Conț[email protected]

Principle QA@ Betfair

Co-Founder Romanian Testing Community

47www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

Testarea ca știință exactă

programare

Modernizarea și scalabilitatea au fost obţinute prin implementarea de noi func-ţionalităţi gen: web sockets, suport pentru protocolul UDP, suport pentru noul async programming model “awayt/assync”.

Să începem cu fișierul de configurare. Vi se pare cunoscut scenariul în care aţi creat un serviciu pe care îl expuneţi printr-un endpoint http/tcp, iar când aţi adăugat o referinţă din aplicaţia client aţi găsit o tonă de configurări pentru un binding? Din feri-cire acest aspect s-a schimbat și lucrurile vor arăta altfel.

Așa arată configurarea default a unui binding într-o aplicaţie client, în WCF 4.0

Așa va arăta in WCF 4.5 !

Frumos. Nu?

Un alt aspect legat de simplitate este faptul că s-au modificat și valorile unor setări pentru ca serviciile să fie “produc-tion ready”. În acest sens au fost modifiate Reader Quotas, Throttles, Timeouts toc-mai pentru a evita multitudinea de excepţii ce se generau din setările default anterioare.

Noile funcţionalităţi din WCF 4.5 tind să se încadreze în două aspecte: simpli-tate și scalabilitate. Cea mai mare problemă care există când vine vorba de WCF este configurarea. Ceea ce s-a dorit de la noua versiune a fost un mod

mai ușor și mai simplu de configurare. Știm cu toţii că nu este ușor să configurezi un serviciu WCF. Într-adevăr, după ce este configurat și merge, devine un mare atuu in orice sistem de aplicații distribuite.

Noutăți în Windows Communication Foundation 4.5

Leonard [email protected]

System Architect@ Arobs

48 nr. 5/2012 | www.todaysoftmag.ro

Un feature nou introdus este suportul pentru moduri de autentificare multi-plă per endpoint. Dacă acest lucru înainte era posibil doar prin crearea mai multor endpoint-uri, acum este posibil prin con-figurarea unui singur endpoint care să suporte de exemplu autentificare Windows si Basic simultan.

Definirea unui endpoint și a unui serviciu se face mai ușor în fișierul de con-figurare prin suportul nou de inllisense, care acum ne oferă o listă de contracte sau

denumiri de clase care pot fi folosite. În cazul în care un element nu a fost

configurat bine, în fereastra de warnings vom fi atenționați despre acest fapt. Acest feature se numește “Validation over configuration”.

WCF 4.5 mai vine cu o noutate în zona de bindings. A fost introdus un nou binding, basicHttpsBinding. Acesta este asemana-tor cu basicHttpBinding, și are umătoarele setări default: SecurityMode=Transport și ClientCredentialType=None.

Configurările acum se pot face în ser-viciu din cod printr-un nou tip, numit ServiceConfiguration. În cazul în care în serviciu se găsește o metodă statică void Configure(ServiceConfiguration config), aceasta va fi apelată by default. Prin acest tip nou de date se pot adăuga behavior-uri noi, endpoint-uri noi, si alte setări uzu-ale. Configurările se pot încărca acum și

dintr-un fișier aflat la o locație diferită pe disc. Acest lucru era posibil înainte doar prin work-around-uri care aduceau over-head și dificultate în mentenanță. Acest feature s-a numit în mod evident Code-based configuration.

Toate aceste feature-uri au fost intro-duse pentru a simplica si ușura lucrul cu WCF.

În continuare vom vorbi despre ce anume s-a adus în plus pe partea de moder-nizare si scalabilitate a acestui framework.

Vom începe cu noul mod în care se pot scrie metode asincrone, Task-based model . Acest feature permite scrierea de cod asin-cron atât pe server cât si apelarea lui de pe client tot în mod asincron. Ca și principiu orice metodă care returnează Task sau Task<T> reprezintă o metodă asincronă pe server. Aceste metode pot fi invocate folo-sind noile keyword-uri: await și async. Să considerăm urmatorul exemplu:

public static async void CopyToAsync(Stream source, Stream destination){ byte[] buffer = new byte[0x1000]; int numRead; while((numRead = await source. ReadAsync(buffer, 0, buffer.Length)) > 0) { await destination.WriteAsync(buffer, 0, numRead); }}

Practic avem o copiere asincronă de stream-uri. Metoda are nevoie de modi-ficatorul async deoarece în interiorul ei folosim operatorul await. În acest fel com-pilatorul știe că este vorba de cod asincron iar când execuția codului va fi gata va con-tinua cu orice alte instrucțiuni mai rămân de executat. În cazul in care folosim await

dar nu punem async în semnătura metodei vom avem o eroare de compilare.

Pentr u comparaț ie voi adăuga același exemplu folosind APM (Async Programming Model), cel uzual cu care am fost obișnuiţi până acum.

Este evident faptul că lucrurile au fost simplificate major. Folosind noul task based model, este aproape la fel de ușor scrierea metodelor asincrone ca și cele sincrone. Trebuie doar ca return type-ul metodei

să fie de tip Task<T> și să adăugaţi keyword-urile await și async.

Revin la partea de bindigs unde a fost introdus UdpBinding. Acesta este folosi-tor în cazul în care se dorește transmiterea datelor către mai mulţi receive-ri, scenarii gen broadcast și multicast . În acest caz nu este atât de important conţinutul mesajelor cât timpul de trimitere. Limitarea este fap-tul că nu are WAS suport.

Un alt feature foarte important este suportul pentru WebSockets. Acestea permit comunicarea bi-direcţională, full duplex, într-un mod mai ușor decât se făcea până acum.

Ca o concluzie, în WCF 4.5 s-a încercat simplificarea si modernizarea platformei de development prin setări “production ready”, intellisense si validare pe fișierele de configurare, support pentru WebSockets, UDP, Task-based model și alte feature-uri. Considerăm că aceste feature-uri sunt utile și bine venite raportându-ne la versiunile anterioare și abia așteptăm să le punem în practică.

public static IAsyncResult BeginCopyTo(Stream source, Stream destination){ var tcs = new TaskCompletionSource();

byte[] buffer = new byte[0x1000]; Action<IAsyncResult> readWriteLoop = null; readWriteLoop = iar => { try { for (bool isRead = iar == null; ; isRead = !isRead) { switch (isRead) { case true: iar = source.BeginRead(buffer, 0, buffer.Length, readResult => { if (readResult.CompletedSynchronously) return; readWriteLoop(readResult); }, null); if (!iar.CompletedSynchronously) return; break;

case false: int numRead = source.EndRead(iar); if (numRead == 0) { tcs.TrySetResult(true); return; } iar = destination.BeginWrite(buffer, 0, numRead, writeResult => { try

{ if (writeResult.CompletedSynchronously) return; destination.EndWrite(writeResult); readWriteLoop(null); } catch(Exception e) { tcs.TrySetException(e); } }, null); if (!iar.CompletedSynchronously) return; destination.EndWrite(iar); break; } } } } catch(Exception e) { tcs.TrySetException(e); } }; readWriteLoop(null);

return tcs.Task;}

public static void EndCopyTo(IAsyncResult asyncResult){ ((Task)asyncResult).Wait();}

tehnologii

49www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINE

sistem distribuit fără nici o problemă. Toate problemele legate de scalabilitate, securi-tate, load-balancing sunt rezolvate de către acesta. O proprietate foarte importantă a acestei infrastructuri este că garantează că nici un mesaj nu este pierdut, fiecare mesaj ajungând la destinaţie odată ce a fost recep-ţionat de Service Bus.

În acest moment când vorbim de Service Bus vorbim de trei componente foarte importante: • Service Bus Queues,• Service Bus Topics,• Service Bus Relay.

Service Bus Queue, despre care o să vor-bim în acest articol, este un serviciu care ne permite să lucrăm cu cozi de mesaje în cadrul Service Bus-ului. Service Bus Topics este destul de asemănător cu Service Bus Queues, diferenţa principală este că un mesaj poate să ajungă la mai mulţi ascul-tători (subscribers), nu doar la unul singur. Service Bus Relay ne permite să integrăm și să expunem servicii WCF care sunt

găzduite pe servere on-premises prin inter-mediul la Windows Azure.

Service Bus Queue este un serviciu care ne permite comunicarea între două module prin intermediul unei cozi de mesaje. Această operaţie se desfășoară în totali-tate asincron, modulele nefiind obligate să aștepte după alte module. Orice mesaj care a fost trimis cu succes la această coadă de mesaje nu o să fie pierdut, acest lucru fiind garantat de către Windows Azure. Chiar și în momentele când nu există un consuma-tor de mesaje, acestea o să fie păstrate de către Service Bus Queue.

Numărul de mesaje dintr-un queue nu este limitat. Limita există doar la capacita-tea maximă pe care o poate avea un queue, aceasta fiind de 5GB. Fiecare mesaj poate avea o dimensiune maximă de 256KB. În interiorul acestuia putem să adaugăm informaţii sub forma de (cheie, valoare) sau orice obiect serializabil. Putem să adaugăm chiar și stream-uri de date, atâta timp cât dimensiunea lor nu depășește

Primul CTP de Windows Azure a fost anunţat în 2008, iar după doi ani a fost lan-sată și versiunea comercială. De atunci și până astăzi, fiecare nouă versiune de Windows Azure a adus noi funcţionalităţi. Dacă în 2010 web role-ul și worker

role-ul erau principalele puncte forte, astăzi Windows Azure este mult mai complex și ne permite să facem lucruri pe care nici nu ni le puteam imagina.

Windows Azure Service Bus ne oferă infrastructura pentru a putea comunica într-un

Radu [email protected]

Senior Software Engineer@iQuest, proiectele pe care lucrează sunt de tip LoB, în general folosind ultimele tehnologii Microsoft. Face parte din grupul entuziaștilor, motiv pentru care ii place să fie la curent cu tot ce apare nou in domeniul IT, in spe-cial din punct de vedere software.

Service Bus Topics din Windows Azure

tehnologii

50 nr. 5/2012 | www.todaysoftmag.ro

capacitatea maximă a unui mesaj. Fiecare mesaj adăugat în Service Bus Queue are un TTL (time-to-live), valoarea maximă acceptată este infinit. În momentul în care TTL expiră, un mesaj este automat elimi-nat din coadă. Pe lânga această proprietate avem disponibilă și o proprietate prin care putem specifica când un mesaj să devină activ în coadă și poate să fie consumat. În acest mod putem trimite un mesaj în coadă care să poată fi procesat doar începând la o dată prestabilită de către noi.

Service Bus Queue, este un serviciu care ne permite să avem un număr nelimitat de producători și consumatori de mesaje. Acest servciu include și un mecanism de detectare automată a duplicatelor. Din punct de vedere a securităţii și a accesului la o coadă de mesaje din Service Bus, acesta poate fi făcut prin intermediul:• Claim-urilor de tip ACS,• Acces pe bază de rol,• Identify provider federation.

La ora actuală Shared Access Signature nu poate fi folosit pentru a accesa o coadă din Service Bus sau orice altă resursă din cadrul Service Bus-ului.

Pentru a putea folosi o coadă sau orice alt serviciu disponibil prin intermediul la Service Bus este necesar să ne creăm un namespace. Un namespace reprezintă un nume unic prin care putem identifica resursele și serviciile pe care le avem dispo-nibile în Service Bus. Acesta poate fi creat de pe portalul Windows Azure, în cadrul secţiunii “Service Bus, Access Control & Caching”. Odată ce avem un namespace ,o coadă poate fi creată prin diferite moduri, începând de la portal până la fișiere de con-figurare sau din cod. Putem să dăm orice nume la o coadă atâta timp cât respectăm următoarele reguli:• Conţine doar cifre, litere mari și

mici,• Conţine doar caractere precum ‘-‘,

‘_’, ‘.’• Nu depășește 256 de caractere.Aplicaţiile care doresc să acceseze Service Bus Queues trebuie să știe trei informaţii: • Endpoint – adresa url prin inter-

mediu l căre ia putem accesa serviciile din cadrul Service Bus. Această adresă are în general forma următoare:

sb://[namespace].servicebus.windows.net/

• SharedSecretIssuer – numele la

issuer (proprietarul namespace-ului)• SharedSecretValue – cheia secretă

pe baza căreia un namespace poate fi accesat. Aceasta se poate regenera în orice moment prin intermediul portalului.

Toate aceste informaţii și locaţia unde trebuie să fie adăugate într-un proiect pot fi găsite pe portalul Windows Azure. Acesta ne poate genera automat XML-ul care tre-buie adăugat. Tot ce ne mai rămâne nouă de făcut este să adăugăm printr-un simplu copy/paste această informaţie. Următoarele exemple o să fie în C#, dar asta nu înseamnă că nu puteţi să folosiţi Service Bus Queues din PHP, Node.js sau orice alt limbaj de programare. Acest serviciu este expus în format REST, iar orice librărie pe care o folosiţi este de fapt un wrapper peste acesta.

Înainte să creăm un queue este reco-mandat să verificăm dacă acesta nu există deja. În cazul în care dorim să creăm un queue cu un nume care deja există va fi aruncată o excepţie. NamespaceManager ne permite să accesăm orice serviciu din cadrul Service Bus-ului.NamespaceManager namespaceManager = NamespaceManager.CreateFromConnectionString( CloudConfigurationManager.GetSetting( “ServiceBusConnectionString”));

QueueDescription queueDescription = new QueueDescription(„FooQueue”);

queueDescription.DefaultMessageTimeToLive = new TimeSpan(0, 10, 30);if(!namespaceManager.QueueExists(„FooQueue”)){

namespaceManager. CreateQueue(queueDescription);//sau namespaceManager.CreateQueue(“FooQueue”);}

După cum se poate observa, o coadă se poate crea specificând doar numele. În cazul în care dorim să setăm anumiţi para-metri cu alte valori faţă de valorile default putem apela la QueueDescription.

Orice mesaj pe care îl adaugăm în queue este de tip BrokeredMessage. În cadrul acestui obiect este necesar să punem toată informaţia care trebuie să ajungă la

consumator. Un mesaj este format din două părţi:• Header –conţine configuraţia mesa-

jului și toate proprietăţile pe care noi vrem să le adaugăm

• Body – conţinutul mesajului. Acesta poate să fie un obiect serializat sau un stream.

Operaţiile pe o coadă se pot desfășura atât sincron cât și asincron. Mecanismul de adăugare a unui mesaj în coada este destul de simplu. În schimb când dorim să extra-gem un mesaj din coadă avem la dispoziţie două mecanisme:• Receive and delete – un mesaj este

luat din coadă și imediat șters• Peek and lock – un mesaj este luat

din coadă și blocat. Acesta urmează să fie șters doar în momentul în care consumatorul specifică acest lucru. Dacă într-un interval predefinit de timp consumatorul nu confirmă că mesajul a fost procesat, Service Bus Queue va face mesajul din nou dis-ponibil pe coadă (valoarea default este de 60 de secunde).

Toate aceste operaţii pot fi făcute prin intermediul unui obiect de tip QueueClient.BrokeredMessage message = new BrokeredMessage(); message.Properties[„key”] = „value”;

QueueClient queueClient = QueueClient.CreateFromConnectionString( connectionString, „FooQueue”);

queueClient.Send(message);

BrokeredMessage messageReceiveAndDelete = queueClient.ReceiveAndDelete();

try{BrokeredMessage messagePeekAndLock = queueClient.Receive();// ... messagePeekAndLock.Complete();} catch(){ messagePeekAndLock.Abandon();}

Operaţiile pe coada de mesaje sunt tranzacţionale, iar atât producătorul cât și consumatorul pot să lucreze cu batch-uri de mesaje. În cazul în care ajungeţi să adă-ugaţi foarte multe date într-un mesaj sau

tehnologii

51www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINEService Bus Topics din Windows Azure

doriţi să adăugaţi conţinutul unui stream într-un mesaj încercaţi să vă gândiţi de două ori dacă aveţi nevoie de această infor-maţie și dacă nu o puteţi pune într-un loc unde atât producătorul cât și consumatorul să o poată accesa (de exemplu în Windows Azure Tables, Windows Azure Blobs). byte[] currentMessageContent = new byte[100];//...BrokeredMessage messageToSend = new BrokeredMessage(new MemoryStream( currentMessageContent));

queueClient.Send(messageToSend);

BrokeredMessage messageToReceive = queueClient.Receive();

Stream stream = messageToReceive. GetBody<Stream>();

După ce se apelează metoda Receive() trebuie să avem grijă dacă obiectul returnat este null. Totodată, thread-ul o să rămână blocat la apelul metodei ReceiveAndDelete până când un mesaj din coadă este dis-ponibil. Fiecare mesaj adăugat în coadă poate să avea atașat un id unic de sesiune (SessionId). Prin intermediul acestei sesi-uni, se poate configura ca un consumator să primească mesajele care au doar un anumit id de sesiune. Aceasta este o moda-litate de a trimite date către un consumator care în mod normal nu ar încăpea într-un singur mesaj. Pe partea de producător trebuie setată doar proprietatea SessionId a mesajului, iar consumatorul trebuie să se folosească de MessageSession, instanţă ce poate fi obţinută apelând metoda “AcceptMessageSession([sessionId])” a QueueClient-ului.MemoryStream finalStream = new MemoryStream();MessageSession messageSession = queueClient. AcceptMessageSession(mySessionId);

while(true){ BrokeredMessage message = session. Receive(TimeSpan.FromSeconds(20));

if(message != null) {// ... message.Complete(); continue; } break;

}

O coadă de mesaje din Service Bus Queues, nu conţine doar un singur queue. Putem spune că un queue conţine mai multe queue-uri. Toate mesajele care nu au putut fi procesate (de exemplu mesajele care au expirat sau când coada a ajuns la capacitate maximă) ajung într-o coadă de mesaje de tip “Death Letters”. Această coadă poate fi accesată, fiind foarte utilă când se face debug sau când avem nevoie să logăm mesajele care nu au putut să fie procesate. În această coadă nu ajung doar mesajele adăugate de către sistem. Aceste mesaje se pot adăuga și din cod prin intermediul metodei DeathLetter a unui BrokeredMessage.

Există un scenariu când această funcţionalitate ne poate fi foarte utilă. Imaginaţi-vă că un consumator de mesaje încearcă să consume un mesaj care nu poate să fie procesat. Consumatorul va încerca la infinit să proceseze acest mesaj. Acest tip de mesaj este denumit “Poison Message”, iar un sistem gândit greșit poate să fie dat peste cap din cauza acestei cozi.

În următorul exemplu încercăm să pro-cesăm un mesaj de trei ori. Dacă nu reușim cu succes, acesta este automat marcat ca și “Poison Message”. while(true){ BrokeredMessage message = queueClient. Receive();

if(message == null) { Thread.Sleep(1000); continue; } try { ... message.Complete() } catch(Exception ex) { if( message.DeliveryCount > 3 ) { message.DeadLetter(); } message.Abandon(); }

}

O referinţă la o coadă de mesaje pen-tru death letters poate fi obţinută în felul următor:QueueClient deathLeterQueue= QueueClient. CreateFromConnectionString( myFooConnectionString, QueueClient.FormatDeadLetterPath( „FooQueue”));

O funcţionalitate aparte a Service Bus Queues este integrarea cu WCF. Un servi-ciu WCF poate fi configurat să folosească cozile de mesaje pentru a putem comunica. Prin acest mod serviciul nostru devine fle-xibil și scalabil. Toate problemele de tip load balancing se rezolvă aproape singure în acest fel. Iar în cazul în care serviciul este căzut, consumatorul va putea trimite în continuare mesaje fără să aibă parte de erori sau aceste mesaje să se piardă. În unele cazuri acest lucru ne poate fi de folos. Totodată prin acest mod putem să expu-nem servicii WCF din reţele private fără să avem probleme de securitate.

Din unele puncte de vedere Service Bus Queues este destul de asemănător cu Windows Azure Queues. Ne putem imagina Service Bus Queues ca și un Windows Azure Queues cu steroizi. Când avem nevoie de features precum garantarea ordinii mesa-jelor, operaţii tranzacţionale, TTL mai mare ca șapte zile sau integrarea cu WCF, atunci Service Bus Queues este soluţia noas-tră. Sunt însă cazuri când Windows Azure Queues este o soluţie mult mai bună. Din această cauză trebuie să comparaţi cele două tipuri de cozi de mesaje oferite de Windows Azure și să vedeţi care este cea mai bună pentru aplicaţia voastră.

În concluzie Service Bus Queues este extrem de puternic și are patru puncte forte care nu trebuie neglijate: • Loose coupling (consumatorul și

producătorul nu trebuie să știe unul de celălalt)

• Load leveling (consumatorul nu tre-buie să funcţioneze non-stop)

• Load balancing (putem să înregis-trăm consumatori și producători foarte ușor)

• Temporary decoupling (producă-torul sau consumatorul poate să fie offline)

52 nr. 5/2012 | www.todaysoftmag.ro

Malware pe Android statistici, comportament, identificare și neutralizare

Din păcate, nici Android nu scapă de atenția hackerilor și a criminalilor ciber-netici care abia așteaptă noile tehnologii să ajungă populare pentru a obține câștiguri informaționale, tehnologice și financiare ilegale. Totuși, cum stă Android în acest moment?

Conform unui studiu realizat de TrendLabs, în primele 3 luni ale acestui an au fost descoperite 5 000 de aplicații malware ca apoi în luna aprilie să se desco-pere aproape 15 000 de aplicații malware, aceștia așteptându-se ca până la sfârșitul anului să se ajungă la aproape 130 000 de aplicații malware mobile. Îngrijorător e că doar 20% dintre aplicațiile mobile au o aplicație dedicată securității, iar drept dovadă, 17 aplicații malware din Google Play au fost descărcate de 700 000 de ori până ca acestea să ajungă să fie eliminate.

Clasamentul comportamental al malware-ului pe Android arată că în top se află aplicațiile de tip Premium Service Abuser cu 48%, urmate de Adware cu 22% și la mică distanță, cu 21%, furtul de date. Uneltele de spionaj ocupă în acest moment doar un procent de 4% ceea ce demon-strează că până acum sunt folosite în scop targetat. Un exemplu de aplicație malware a fost SMSZombie, nu prea populară în Europa și SUA pentru că se adresa unui serviciu folosit predominant de chinezi

– Mobile SMS Payment Service. Aplicația a infectat 500,000 de device-uri și au tri-mis bani în conturile unor profile de jocuri online.

Ce opțiuni are o aplicație de spionaj publică?

Pentru aproape 16$ pe lună sau chiar mai puțin, există aplicații de spionaj ale tele-foanelor cu Android (atenție, și nu numai) extrem de complexe și de bine puse la punct ce se adresează în mod public părinților ce vor să fie mai aproape de copiii lor, mana-gerilor firmelor ce suspectează spionajul industrial dar și organelor guvernamentale. Controlul aplicațiilor se face atât prin SMS cât și prin Internet, atunci când este posibil. Poți înregistra convorbirile și vizualiza isto-ricul apelurilor, poți citi SMS-urile primite și trimise, poți defini cuvinte cheie pentru aceste SMS-uri, poți înregistra zgomotul din jur până la peste 10 metri, poți citi email-urile de pe GMail sau de pe vreun serviciu definit în mod explicit în aplicația de email default de la Android, poți accesa toate contactele stocate pe telefon, toate activitățile din calendar, poți vedea foto-grafiile, videoclipurile, muzica; există acces la istoricul browserelor, monitorizarea locației cu sau fără GPS și lista continuă. Mă repet, aceasta poate face doar o aplicație de spionaj publică. Monitorizarea rețelelor Wifi, obținerea controlului asupra rețelelor, instalarea de exploit-uri 0-day pe compute-rele din rețea, monitorizarea bluethoot ar putea completa lista.

Ce opțiuni ar putea avea un botnet pentru Android?

Deși situațiile de acest gen au fost puține până acum, ne putem aștepta în

Android, sistemul de operare pentru telefoanele mobile de tip Smartphone, cel mai popular mobile OS din SUA și poate cel mai popular de pe planetă se bucură de o atenție tot mai categorică la nivel mondial și aceasta datorită diversității gadget-urilor pe care este instalat.

tehnologii

Andrei Avădă[email protected]

Fondator si CEO DefCampCEO worldit.info

tehnologii

53www.todaysoftmag.ro | nr. 5/2012

TODAY SOFTWARE MAGAZINEtehnologii

orice clipă la un adevărat botnet popula-rizat prin intermediul Google Play + ceva magic. Să ne imaginăm următorul scena-riu – o aplicație nouă, aparent ce rezolvă o nevoie a publicului larg a fost încărcată în Google Play. După ce este descărcată, această dă automat Like, +1 și un punctaj bun aplicației din market, eventual lasă un comentariu random dintr-o listă predefi-nită, poate chiar încearcă să lege un dialog între doi “clienți”. Aplicația malware exploa-tează o vulnerabilitate ce permite obținerea dreptului de root pe telefonul mobil. Printre altele face un ping la un website hijacked, ce are un serviciu de comunicare special instalat pentru malware. Acesta îi comunică o listă cu website-uri hijacked descentralizate. Bun, face un fingerprinting pe tot mobilul (operațiunea se poate face și înainte de a obține root acces și impli-cit backdoor-ul), se decide dacă e necesară vreo unealtă suplimentară de la unul din servere. Dacă nu, se colectează informații precum – adrese de email, numere de telefon, conversații, istoric, cookie-uri, conturi, s-ar putea infecta telefoane până în momentul în care ajunge la țintă, se rea-lizează operațiunea pentru care a fost creat, apoi se diluează. Restul e variabil. Problema rămâne totuși răspândirea – prin rețele wifi, pe alte telefoane oferind mesaje personali-zate prietenilor în funcție de țara și orașul unde sunt, prin 0-day-uri, prin construirea permanentă a unor aplicații infectate.

O introducere în securitatea pe Android

Android este o platformă mobilă modernă ce a fost dezvoltată cu gândul la deschidere. Aplicațiile de pe Android se folosesc de tehnologia hardware și software pentru a oferi utilizatorilor experiența ide-ală. Pentru a proteja valoarea creată de sistemul de operare, platforma oferă un mediu ce asigură securitatea utilizatorilor, a datelor, a aplicațiilor, a device-ului și a rețelei. Securizarea unei platforme Open Source necesită o arhitectură robustă de securitate dar și de un proces de securitate riguros. Android a fost gândit astfel încât securitatea sa fie împărțită în mai multe straturi, oferind astfel o flexibilitate sporită și protejând utilizatorii platformei.

Programul Android de securitateProcesul Android de securitate începe

în primele etape ale dezvoltării prin cre-area unui model de securitate complet și

configurabil. Fiecare facilitate majoră a platformei este revizuită de ingineri. Pe parcursul dezvoltării componentele sunt revizuite de Android Security Team, Google Information Security Engineering Team și consultanți independenți în securitate. Scopul acestor analize este identificarea slăbiciunilor și posibilelor vulnerabilități cu mult înainte ca acestea să fie publicate Open Source. În momentul publicării, Android Open Source Project permite întreținerea și revizuirea codului de un număr nedefinit de entuziaști și voluntari. După momentul în care a fost publicat codul sursă, echipa Android reacționează rapid la orice raport cu privire la o potențială vulnerabilitate pentru a se asigura că riscul ca utilizatorii să fie afectați este minimalizat în cel mai scurt timp posibil. Aceste reacții includ update-uri rapide, eliminarea unor aplicații din Google Play sau eliminarea unor aplicații din device-uri.

Arhitectura platformei de securitate Android

Android urmărește să fie cel mai sigur sistem de operare pentru platformele mobile, încercând să garanteze:• protejarea datelor de la utilizatori,• protejarea resurselor sistemului

(include și rețeaua),• izolarea aplicațiilor.

Pentru a atinge aceste puncte, trebuie atinse niște puncte cheie în arhitectura platformei :• securitate robustă la nivel de OS

prin kernelul de Linux,• Sandbox pentru aplicații,• comunicare securizată între procese,• semnarea aplicațiilor,

• definirea unor permisiuni pentru aplicații și utilizatori.

Mai multe detalii despre arhitectură Android se găsesc pe source.android.com.

Ce aplicații Anti-Virus pentru An-droid există?

Conform rezultatelor AV-Comparatives din septembrie 2012, cele mai eficiente aplicații mobile de securitate sunt: avast! Mobile Security, BitDefender Mobile Security, ESET Mobile Security, F-Secure Mobile Protection, IKARUS mobile.secu-rity, Kaspersky Mobile Security, Lookout Premium, McAfee Mobile Security, Qihoo 360 Mobilesafe, SOPHOS Mobile Security, WEBROOT, eficiență fiind de peste 93% în ordine descrescătoare.

ConcluziiDeși statisticile arată îngrijorător, rea-

litatea e că majoritatea aplicațiilor malware de până acum nu au un comportament foarte periculos. În același timp, tehno-logiile anti-virus moderne se mută și pe mobile cu o viteză surprinzătoare, majo-ritatea jucătorilor de pe piață având o soluție de securitate pentru smartphone deja pregătită. Mai mult decât atât, echipa de dezvoltare Android susține că ultima versiune a sistemului de operare aduce un plus de siguranță, după cum o confirmă și unii specialiști în securitate independenți. Din experiență, tind să cred că problema virușilor pe telefoanele mobile va fi la fel de sensibilă ca pe computere în scurt timp și că va trebui să fim din ce în ce mai atenți la ce instalăm. Stay safe, stay open!

54 nr. 5/2012 | www.todaysoftmag.ro

GoguȘefu’ întredeschise ușa de la birou, iar

Gogu văzu imediat pe faţa lui că ceva nu e în regulă. Adevărul e că, dacă s-ar fi uitat în jur, ar fi văzut că întreg biroul era stu-pefiat: încă nu le venea să creadă, nimeni nu-i auzise până acum pe Gogu și pe Mișu certându-se și ţipând unul la altul. Păi dacă e căpos?! își zise Gogu. Dar stai așa, că ne lămurim noi acum…

- Șefu’, bine c-ai venit. Ai două minute să ne clarifici o problemă?

- O problemă?! Păi la ce scandal se aude la voi, mira-m-aș să fie vorba despre o singură problemă! S-aud și eu, care e mărul discordiei?

- Ce măr, Șefu’, crezi ca ne arde de joacă? se băgă și Mișu în discuţie, roșu în obraji, cu ochii sticlind și cu respiraţia întretăiată de parcă ar fi alergat la maraton. Lămurește-l mata pe colegul Gogu, că eu argumente nu mai am!

- N-ai, că n-ai de unde! De-aia te și enervezi și ridici tonul! nu se putu abţine Gogu.

Șefu’ se prinse că discuţia probabil dura déjà de o bună bucată de vreme, era evident – pentru cine îl cunoștea, desigur - că Gogu făcea eforturi să pară calm, dar era la fel de “prins” ca Mișu (doar că nu era la fel de roșu). Erau necesare măsuri ime-diate așa că Șefu’ își luă aerul sfătos și vocea joasă, se îndreptă de spate și lăsă cuvintele să iasă clar și răspicat:

- Cred că e cazul să vă calmaţi amândoi și să îmi explicaţi – calm, fără să ridicaţi tonul și fără să vorbiţi deodată – despre ce e vorba. Evident se lansaseră imediat amândoi în explicaţii așa că Șefu’ se văzu nevoit să repete:

- Calm, fără să ridicaţi tonul și fără să vorbiţi deodată, am spus. Gogule, explică tu.

Gogu încercă să se abţină și să nu dea drumul la zâmbetul victorios (era clar că eu explic, sunt mai vechi și clar mai price-put) și, după ce luă – ușor teatral - aer în piept, începu să explice:

- Uite Șefu’ despre ce e vorba: pirami-dele din Egipt au fost construite acum vreo cinci mii de ani, corect până aici?

- Corect, Gogule.- Marele zid chinezesc e mai recent, are

probabil in jur de 2200 de ani, nu?- Așa e, Gogule.- Piramidele mayașe sunt si mai

recente, dar tot au 1500 de ani.

- Ce e asta, Gogule, lecţie de istorie?! își pierdu Șefu’ răbdarea.

Mișu vru să intervină, dar privirea lui Șefu’ îl opri. Gogu continuă, neabătut:

- Construcţia Taj Mahal-ului a durat 22 de ani și s-a finalizat în secolul 17. Turnul Eiffel a fost realizat mult mai recent și este și el o capodoperă arhitectonică.

- Ajungem și noi undeva cu toate aceste afirmaţii?

- Se înscriu toate aceste realizări extra-ordinare în categoria “proiecte”? continuă neabătut Gogu.

- Da, măi Gogule, da…- Și-atunci – încheie el victorios – este

că există managementul de proiect de 5000 de ani?!

Mișu – care trecuse de la roșu la vișiniu – era în pragul unui infarct așa că explodă:

- Managementul de proiect – mai citește și tu o carte, căpos megalitic! – a apărut în anii 1950. E suficient să te uiţi pe net, cu un minim de efort găsești infor-maţia… Și dacă nu era management de proiect, nu erau nici proiecte, recalcitrant perimat!

Pe Șefu’ îl pufni râsul și nu se stăpâni, începu să râdă tare, sănătos și cu poftă, fără să dea semn că ar vrea să se oprească. Încet, încet, cei din biroul se molipsiră și înce-pură să râdă și ei. Cei doi eroi ai noștri se uitau la el sideraţi, dar era imposibil să nu te molipsești de râsul lui așa că se treziră și ei zâmbind întâi, iar apoi își dădură dru-mul și ei la râs. Hohotind, Gogu remarcă în sinea sa: numai Șefu’ poate face comedie dintr-un scandal de proporţii. După ce se mai liniștiră puţin, Șefu’ se așeză comod pe un birou, cu picioarele atârnând, pre-gătindu-se de explicaţie. Se vedea clar că îi făcea plăcere:

- Măi, frumoasă temă mi-aţi ridicat la fileu, dar tot nu merita să vă agitaţi în halul ăsta. Hai să vă spun cum stă treaba cu pro-iectele și managementul lor. Prin definiţie, proiectele sunt procese complexe, relativ unice pentru compania care le execută. Ţineţi minte când am lansat ultimul nos-tru produs, acum două luni? Realizarea și lansarea lui a fost – pentru noi – un pro-iect. Acum realizăm același produs în serie iar activitatea aceasta se desfășoară prin procese. Adică odată ce știm cum se face, putem să executăm totul prin procese pe care le cunoaștem și le conducem aplicând conceptele managementului operaţional.

Pentru proiecte aplicăm managementul proiectelor. Dar am acum o întrebare pen-tru voi: ce se întâmplă dacă eu n-am idée despre ce înseamnă proiect și managemen-tul proiectelor, aș putea totuși să realizez și să lansez un produs nou?

- Păi, ce, acu’ cinci ani aveam noi habar de management de proiect – se băgă în vorbă Zoli – și tot aveam câte un produs nou pe an.

Ceilalţi aprobară în tăcere. Se pare ca “povestea” Șefului îi prinse pe toţi. Acesta continuă:

- Corect. Sigur că făceam. Doar că nu ne ieșea intotdeauna exact cum ne închi-puiam, costurile nu erau urmărite iar termenele se lungeau mai mereu. Lucram după metodele noastre, exact cum lucrau și egiptenii și chinezii la construcţiile lor. Nu erau ei pasionaţi de a face economie sau de a respecta cu stricteţe niște termene. Exemplele tale, Gogule, sunt exemple de reușite din istoria omenirii, dar sunt și alte exemple, sute, mii de iniţiative care au fost începute dar niciodată finalizate, tocmai din cauza complexităţii lor.

- Sagrada Familia, murmură Mișu, iar Șefu’ dădu din cap a aprobare:

- Și mai sunt multe altele. Ideea de proiect a apărut atunci când s-a încercat aplicarea unor metode noi care să asigure succesul proceselor complexe, riscante, cu investiţii considerabile. Managementul proiectelor înseamnă, de fapt, acordarea unei atenţii manageriale sporite, concreti-zată prin numirea unui manager de proiect și a unei echipe care să fie responsabile de realizarea procesului complex și unic – acum numit proiect. Voi certăreţilor, aveaţi fiecare și dreptate și v-aţi și înselat amân-doi: exemplele lui Gogu sunt într-adevăr proiecte, așa cum le înţelegem noi azi, dar cei care au participat la realizarea lor nu știau asta și nici n-aveau cum să aplice managementul de proiect. Și gata pauza, hai înapoi la muncă, auzi la ei: “căpos megalitic”...

diverse

Simona Bonghez, [email protected]

Speaker, trainer și consultant în managementul proiectelor,

Owner al Confucius Consulting

powered by

sponsori