Tsm 5 2012 ro

Page 42

programare

loguri și am văzut ceva de genul: “value is: Car@29edc073”? Da, foarte enervant ș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 starea 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 anterior. 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 concatenării cu un string) și am putea evita un NullPointerException, dacă “car” este null. Pentru cele trei metode, Apache Commons Lang 3 (http://commons.apache.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/objectmethods/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 dintro 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:

5 practici Java pe care le folosesc

Verifică validitatea parametrilor unei metode

Ni m ă nu i nu î i p l a c e c a N P E (NullPointerException) să apară in stacktrace-ul codului său. Nici mie. Iată câteva tehnici de a evita acest lucru: a. Folosește JavaDoc pentru documentarea parametrilor de intrare. Problema ar fi că majoritatea developerilor 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 paradigma “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, deasemenea, 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 înainte de a executa orice operație. private void divide(int a, int b) { ….. }

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

O modalitate de a impune această practică este limitarea numărului de caractere 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.

42

nr. 5/2012 | www.todaysoftmag.ro

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 probleme apărute pot fi rezolvate în codul client (de exemplu, obiectul 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 MyClaass sau java –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 despre 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 parametrilor de intrare poate fi problematică în așa numita “fereastră de vulnerabilitate” În perioada dintre verificarea parametrului ș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.


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.