Documente Academic
Documente Profesional
Documente Cultură
gș e‐content
pentru învățământul superior tehnic
Instrumente pentru Dezvoltarea Programelor
p g
S
Sumar ( i
(prima parte)
)
Erori Java comune
Câteva elemente de ghidaj în scrierea de cod Java
Câteva elemente de ghidaj în scrierea de cod Java
Refactorizare
Modularitate
M d l it t
Ascunderea Informaţiilor
IDP – Instrumente pentru Dezvoltarea Programelor 2
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
E iJ
Erori Java Comune
C
To err is human,
but to really foul things up
you need a computer.
(Paul Ehrlich)
IDP – Instrumente pentru Dezvoltarea Programelor 3
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
IDP – Instrumente pentru Dezvoltarea Programelor 4
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
S
Suprascrieri cu semantici diferite
i i i i dif i
Aveţi grijă ca orice metodă suprascrisă să păstreze semantica metodei originale
Altfel:
Altfel: posibil comportament ciudat în părţi ale programului ce par a fi
posibil comportament ciudat în părţi ale programului ce par a fi
implementate corect
Exemplu: folosirea in NZ a “Goods and Services Tax” conform cazului in
; p
Germania; semantici incompatibile!!!
Gestiunea Excepţiilor
Gestiunea Excepţiilor
În Java: multe excepţii trebuie fie prinse, fie declarate
Adesea excepţiile sunt prinse fără o gestionare adecvată
Problemă: atunci când este aruncată o excepţie acest lucru nu mai devine vizibil
Problema ce a cauzat excepţia poate cauza diverse alte probleme mai târziu
public double reciprocal(double x) {
double y = 0;
try {
y = 1/x;
/ ; // ArithmeticException p for x==0
} catch (Exception e) {} // no handling
return y; // returns 0 for x==0
}
…
} catch (Exception e) {
y p ( );
System.out.println(e);
}
…
IDP – Instrumente pentru Dezvoltarea Programelor 7
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
ArrayStoreException IndexOutOfBoundsException
Object x[] = new String[3]; Object x[] = new String[3];
x[0] = new Integer(0); x[3] = "hello";
IDP – Instrumente pentru Dezvoltarea Programelor 8
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Java Coding Guidelines
IDP – Instrumente pentru Dezvoltarea Programelor 9
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Convenţii de nume
1. Numele claselor şi interfeţelor întotdeauna încep cu litere mari
ş ţ p
e.g. Demo, Panel, GridbagLayout
2. Numele membrilor, parametrilor metodelor şi a variabilelor locale încep cu
litere mici, e.g. getMax, start
3. Se foloseşte CamelCase, i.e. un cuvânt nou este “separat” printr‐o literă
mare, e.g. getMainPanel
4. j
Numele de pachete sunt scrise cu litere mici, e.g. java.awt.color
5. Constantele static final ar trebui scrise cu litere mari, cu cuvinte
separate prin underscore ("_"), e.g. MIN_WIDTH
6. Numele de parametrii de tip pentru elemente generice ar trebui să conţină o
Numele de parametrii de tip pentru elemente generice ar trebui să conţină o
singură literă mare, e.g. List<T>
7. Câteva alte convenţii:
• Prefixe de nume pentru interfeţe, e.g. ICollection
p ţ , g
• Prefixe de nume pentru variabile private, e.g. _size
IDP – Instrumente pentru Dezvoltarea Programelor 10
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Al l
Altele...
Gestiunea condiţiilor de eroare (e.g. throw and handle Exception)
Comentariile aferente codului, în mod particular atunci când nu este clar ce
funcţie este implementată de o secvenţă de cod
Comentariile se pun la începutul unei clase/metodă/variabilă
La ce e utilă clasa/metoda/variabila?
La ce e utilă clasa/metoda/variabila?
De asemenea se comentează anumite instrucţiuni “cheie”
Nu se folosesc căi absolute de fişiere în codul sursă pentru că computere diferite
au foldere diferite
au foldere
(e.g. “c:\myfolder\myfile.txt”)
Se folosesc în schimb căi relative la folderul aplicaţiei
(e.g. “subfolder\myfile.txt”)
Indentaţia urmăreşte structura programului
d i ă l i
Adăugarea unei linii goale între blocuri logice de instrucţiuni din cadrul aceleaşi
metode
Definirea unei singure interfeţe/clase într‐un fişier
IDP – Instrumente pentru Dezvoltarea Programelor 11
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Refactorizare
IDP – Instrumente pentru Dezvoltarea Programelor 12
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Refactorizarea
“Arta de a îmbunătăţi designul codului existent într‐un mod corect”
Rescrierea codului sursă pentru a îmbunătăţi designul sau modul de
înţelegere ("cleaning
înţelegere ( cleaning it up
it up“ ‐ XP)
Refactorizarea poate schimba modul CUM funcţionează codul dar NU CE face
acesta (conservarea semanticii)
Nu se referă la repararea de bug‐uri
Nu se referă la repararea de bug‐uri sau adăugarea de noi funcţionalităţi
sau adăugarea de noi funcţionalităţi
Modificările pot fi minore sau foarte mari
Modificările pot fi făcute asupra mai multor fişiere sursă simultan
Încurajează
Încurajează programarea exploratorie, rescrierea codului, calitatea mărită a
programarea exploratorie rescrierea codului calitatea mărită a
codului livrat
Cazurile de test ajută la verificarea că modificările nu duc la modificarea
semanticii
Lucrările despre refactorizare descriu indicatori pentru probleme comune de
proiectare (“smells”) şi posibile soluţii (“refactorings”)
Fowler, Martin (1999). Refactoring. Improving the Design of Existing Code.
, ( ) f g p g g f g
Addison‐Wesley.
Wake, William C. (2003). Refactoring Workbook. Addison‐Wesley.
IDP – Instrumente pentru Dezvoltarea Programelor 13
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Si li
Simplitate
Simplitatea
Simplitatea reprezintă un principiu foarte important pentru refactoizare:
reprezintă un principiu foarte important pentru refactoizare: putem
putem
rescrie codul a.î. să devină mai simplu (de înţeles)?
Evitarea complexităţii inutile, e.g.
Înlăturarea
Înlăturarea codului neutilizat/nenecesar
codului neutilizat/nenecesar
Folosirea de nume clare, sugestive şi simple
În XP: nu se foloseşte mai multă codare decât absolut necesar
“Hack‐urile
Hack‐urile deştepte
deştepte” nu au întotdeauna valoare, decât de a confuza şi mai mult
nu au întotdeauna valoare decât de a confuza şi mai mult
oamenii
Codarea pentru oameni: claritate, accesibilitate, înţelegere
Capacitatea de mentenanţă
Capacitatea de mentenanţă mai importantă decât performanţa
mai importantă decât performanţa
(legea lui Moore vs. costurile mari ale mentenanţei software)
KISS ("Keep it Short and Simple"), Occam's razor, Einstein: "everything should be
made as simple as possible, but no simpler"
IDP – Instrumente pentru Dezvoltarea Programelor 14
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
IDP – Instrumente pentru Dezvoltarea Programelor 15
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Cod duplicat
Cod duplicat
Simptome:
Două fragmente de cod arată (aproape) identic
Două
Două fragmente de cod implementează (aproape) acelaşi lucru
fragmente de cod implementează (aproape) acelaşi lucru
Cauze:
Mai mulţi programatori lucrând independent
Duplicarea poate să nu fie chiar atât de uşor de observat sau nu a fost anticipată
Duplicarea poate să nu fie chiar atât de uşor de observat sau nu a fost anticipată
Programatorii adesea copiază şi adaptează cod în funcţie de necesităţile lor
curente
Soluţia: extragerea de metode
Soluţia: extragerea de metode
Dacă codul duplicat implementează acelaşi lucru: alegerea şi substituirea
algoritmului superior (sau chiar merge între cele două)
Dacă duplicarea apare în clase pereche: extragerea de metode şi câmpuri şi
plasarea lor într‐o superclasă; formarea unor metode şablon
l l î t l ă f t d bl
Exemple:
Mici task‐uri auxiliare (e.g. sortarea numerelor, găsirea elementelor) sunt
rezvoltate ad hoc
ad hoc
Cerinţe înrudite duc la implementearea de UI sau logică a programului similare
IDP – Instrumente pentru Dezvoltarea Programelor 18
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Metode şablon
Metode şablon
Algoritmul este adesea acelaşi pentru mai multe tipuri de date înrudite
(siblings), cu diferenţe doar de detalii
Id
Idea: descrierea paşilor comuni, generali ai algoritmului într‐o metodă a
d i il i li i l i l iî dă
superclasei (metodă şablon);
detaliile sunt plasate în metode ajutătoare a subclaselor
abstract class Game { class Chess
int numPlayers; extends Game
abstract void makeTurn(int player); { …
abstract int getWinner(); Chess() {
final void play() { numPlayers = 2;
while(getWinner()==0) }
for(int p p=1;p<=numPlayers;p++)
p y p void makeTurn
makeTurn(p); (int p) { … }
System.out.println(
"Player "+getWinner()+" wins"); int getWinner()
} { … }
} }
IDP – Instrumente pentru Dezvoltarea Programelor 19
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
“Ask
Ask What Kind
What Kind” Anti
Anti‐Pattern
Pattern
(Moştenirea Simulată)
Simptom: metoda foloseşte switch sau mai multe if‐uri (posibil cu
instanceof) pentru a distinge între diverse tipuri de obiecte
Cauze: concepte înrudite dar diferite nu sunt reprezentate în clase diferite, lipsa
polimorfismului la nivel de metodă
Soluţia:
Reprezentarea diferitelor tipuri în diverse subclase
Implementarea comportamentului specific în subclase prin suprascrierea metodelor
Metoda specifică subclasei este class C {
invocată automat (“don’t ask what kind”) void m() { generic }
}
class C { class
l A extends
t d C {
String type; void m() { m1 }
void m() { }
if(type.equals("A")) m1();
class B extends C {
if(type.equals("B")) m2();
void m() { m2 }
} }
}
IDP – Instrumente pentru Dezvoltarea Programelor 20
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
R f
Refactorizarea în Eclipse
i î E li
Selectare cod sursă,
right‐click şi folosire submeniu Refactor
Refactorizarea cu preview al modificărior
(modificări individuale pot fi acceptate)
Cu selectarea numelui unei metode:
Rename, Inline, Pull Up, Push Down,
Introduce Indirection, Change Method Signature, …
Cu selectarea numelui unui câmp:
Cu selectarea numelui unui câmp:
Rename, Pull Up, Push Down, Encapsulate Field,
Generalize Declared Type, …
Cu selectarea numelui unei clase:
Rename, Move, Extract Interface, Extract Superclass,
Use Supertype Where Possible, …
Cu selectarea unor instrucţiuni: Extract Method
Cu selectarea unor expresii: Extract Constant
IDP – Instrumente pentru Dezvoltarea Programelor 21
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Sumar
Există erori Java comune, e.g.
Accesarea membrilor non‐statici din metode statice
Probleme de suprascriere
Gestiunea insuficientă a erorilor
Gestiunea insuficientă a erorilor
Convenţiile de nume şi alte reguli trebuie respectate
Refactorizarea presupune îmbunătăţirea designului codului existent
presupune îmbunătăţirea designului codului existent
“Refactoring” ‐ soluţii la probleme comune de design adesea indicate prin
“smells”, e.g.
Metode lungi sau clase mari
Cod duplicat
Antişabloane precum
precum "magic
magic numbers
numbers" şi
şi "ask
ask what kind
kind"
IDP – Instrumente pentru Dezvoltarea Programelor 22
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Modularitate
IDP – Instrumente pentru Dezvoltarea Programelor 23
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
M d l i
Modularitate
Sistemele complexe pot fi adesea descompuse în părţi mai mici numite
module
Modul: componentă de sine stătătoare a unui sistem
Are o interfaţă bine‐definită cu alte module
Separă interfaţa de implementare
Separă interfaţa de implementare
Adesea corespunde unui set de tipuri de date sau cod, similar pachetelor Java
Sistemul modular (i.e. sistem compus din module) este mai uşor de înţeles,
dezvoltat şi menţinut
dezvoltat şi menţinut
Atunci când lucrăm cu un modul detaliile celorlalte module pot fi ignorate
(separaţia preocupărilor)
Modulele pot fi dezvoltate independent
O mai bună izolare între module poate preveni ca un defect dintr‐un modul să
cauzeze defectarea altor module
Modulele pot fi schimbate cu alte module
M d l l
Modulele pot fi refolosite în alte sisteme
t fi f l it î lt i t
IDP – Instrumente pentru Dezvoltarea Programelor 24
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
M d l i
Modularitate
Component frameworks
Component frameworks
Suportă dezvoltarea şi conectarea unor module
Format pentru specificarea interfeţelor de module
p p ţ
Funcţionalitate pentru încărcarea, conectarea, şi rularea
modulelor
Module interconnection languages
Permit specificarea interconectării modulelor într‐un sistem la
un nivel înalt
un nivel înalt
Programming‐in‐the‐small: codarea unui modul
Programming‐in‐the‐large: asamblarea unui sistem din
g g g
module
IDP – Instrumente pentru Dezvoltarea Programelor 25
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
M d l i
Modularitate
Exemplu: procesarea
Exemplu: multimedia stream processing
imaginii cu Blender
Audio
Denoiser Mixer
Source Ch1
Audio MPEG4
Normalizer Ch2 Encoder
Source
Video NTSC to PAL Audio In
Source Converter Video In 26
IDP – Instrumente pentru Dezvoltarea Programelor 26
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
S
Separarea preocupărilor
ă il
Cum se poate gestiona eficient complexitatea unui sistem?
Separation of concerns
S ti f (S C)
(SoC)
Separarea problemelor (spargerea problemelor mari în piese mici) şi
concentrarea pe rezolvarea uneia la un moment dat
Spargerea programului în funcţionalităţi distincte ce se suprapun cât mai
Spargerea programului în funcţionalităţi distincte ce se suprapun cât mai
puţin posibil
Concern: o bucată a unui program, adesea o funcţionalitate sau un
comportament particular al programului
Diverse moduri de implementare
Abordarea tradiţională bazată pe modularitate
În OO: separarea preocupărilor în clase şi metode
În UI‐uri: separarea conţinutului de prezentare şi a prezentării de logica
aplicaţiei
Service‐Oriented Architecture (SOA): împărţirea funcţionalităţii între diferite
servicii(‐web)
servicii( web)
Aspect‐Oriented Programming (AOP): separarea preocupărilor în "aspecte"
IDP – Instrumente pentru Dezvoltarea Programelor 27
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Coeziunea şi cuplarea
Coeziunea şi cuplarea
Regulă pentru proiectarea modulelor: “cuplare slabă, coeziune mare”
Coeziunea: măsură a cât de bine lucrează împreună liniile de cod sursă ale unui modul
pentru a oferi o anumită funcţionalitate În programarea OO reprezintă gradul în care o
pentru a oferi o anumită funcţionalitate. În programarea OO, reprezintă gradul în care o
metodă implementează o singură funcţie. Metodele ce implementează o singură funcţie
sunt descrise ca având coeziune puternică.
Un modul trebuie să fie puternic coeziv
Ar trebui să formeze o unitate de sine‐stătătoare având o funcţie precisă
Părţile din modul lucrează împreună într‐o manieră strâns cuplată
Între module trebuie să existe cuplare slabă
Puţine dependenţe între module
P ţi d d ţ î t d l
Un modul este independent de implementarea internă a altui modul
Modificarea implementării unui modul nu necesită modificarea altor module
Interacţiunea dintre module este restricţionată (prin intermediul unui interfeţe stabile)
ţ ţ p ţ
Fiecare modul ar trebui să poată fi înţeles fără a necesita înţelegerea detaliilor altor module
Coeziunea şi cuplarea sunt adesea înrudite: cuplare slabă presupune coeziune puternică
şi vice versa
În OO: mai puţine conexiuni între clase (low coupling) dacă grupăm metode înrudite ale
unei clase împreună (high cohesion)
IDP – Instrumente pentru Dezvoltarea Programelor 28
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
C l
Cuplarea în Programarea OO
î P OO
Cuplarea este crescută între două clase A
Cuplarea este crescută între două clase A şi B dacă:
A are un atribut ce referă pe (are tipul) B
A apelează o metodă a lui B
A are o metodă ce referenţiază
are o metodă ce referenţiază B
(via return type, parametru sau variabilă locală)
A este o subclasă a (sau implementează) B
Dezavantajele cuplării strânse includ:
D j l lă ii â i l d
Modificările unei clase adesea forţează modifică în alte clase
Greu de înţeles o clasă izolată
Greu de refolosit sau testat o clasă deoarece clasele dependente trebuie
să fie şi ele disponibile
Cuplarea slabă poate fi atinsă prin limitarea responsabilităţilor
p p p p ţ
unei clase/pachet
IDP – Instrumente pentru Dezvoltarea Programelor 29
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
S
Spaghetti Code
h tti C d vs. Modular System
M d l S t
Spaghetti Code
Conexiuni hazardoase, probabil crescute de
Conexiuni hazardoase, probabil crescute de‐aa
lungul timpului
Nu există grupuri coezive
Cuplare strânsă: interacţii
Cuplare strânsă: interacţii sporite între părţi
sporite între părţi 10 părţi,
ă ţi 13 conexiuni
i i
aleatoare
Trebuie înţeles totul sau nimic
Modular System
Coeziune puternică în module
p
Cuplare slabă între module
Modulele pot fi înţelese separat
Interacţiile dintre module sunt bine‐înţelese şi 10 părţi, 13 conexiuni,
specificate în detaliu 3 module
IDP – Instrumente pentru Dezvoltarea Programelor 30
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Exemplu: Windows NT
Exemplu: Windows NT
Baza lui WinXP
Arhitectură stratificată
Modulele suprapuse unele
peste altele
Adesea un nivel poate accesa
numai nivelul de sub el
Cel
Cel mai de jos nivel vorbeşte
mai de jos nivel vorbeşte
direct cu hardware‐ul
Cu cât mai sus, cu atât mai
,
multă abstractizare introdusă
faţă de hardware‐ul fizic
IDP – Instrumente pentru Dezvoltarea Programelor 31
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Exemplu: Joc 3D
Exemplu: Joc 3D
Collision
AI
Detection
Scripting
Engine
g
Physics Animation
Engine Engine
Sound
un Scene
c n Rendering
g
Engine Manager Engine
Input
p
Subsystem
IDP – Instrumente pentru Dezvoltarea Programelor 32
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
E
Exemplu: Google
l G l
Încărcarea de date necesită
paralelism puternic
Mai multe module lucrând
concurent şi asincron
concurent şi asincron
Arhitectură scalabilă
Comunicaţia
Comunicaţia adesea se
adesea se
desfăşoară prin intermediul
unor baze de date
Modulele
Modulele pot fi optimizate
pot fi optimizate
în mod independent
IDP – Instrumente pentru Dezvoltarea Programelor 33
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Ascunderea Informaţiei
Out of sight,
out of mind.
IDP – Instrumente pentru Dezvoltarea Programelor 34
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
A
Ascunderea informaţiei
d i f i i
Ascunderea informaţiei ce nu trebuie să fie vizibilă pentru a
folosi o anumită clasă/modul/program
folosi o anumită clasă/modul/program
Prea multă informaţie poate produce confuzie: ce este important
pentru folosire şi ce nu?
Prea multă informaţie poate duce la dependenţe de nedorit
Dacă aspectele interne sunt vizibile & accesibile, cineva ar putea să le
folosească sau chiar să le modifice (e.g. crearea unui “hack” pentru a folosi
ceva într o manieră nedorită)
ceva într‐o manieră nedorită)
Dacă aspectele interne sunt modificate atunci codul extern ce se baza pe
ele s‐ar putea să nu mai funcţioneze
Permiterea
Permiterea numai accesului restricţionat oferă mai multă
numai accesului restricţionat oferă mai multă
flexibilitate
Clasa/modulul/programul poate fi schimbată fără a afecta alte
componente
Multe decizii de proiectare pot fi ascunse iar proiectul sistemului poate
evolua fără a interfera
IDP – Instrumente pentru Dezvoltarea Programelor 35
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Scop
Locul unde declarăm o variabilă determină modul în care poate fi accesată
(i.e. Scopul acesteia)
Scopul unei variabile ar trebui să fie întotdeauna cât mai restrâns cu putinţă
Dacă o variabilă poate fi accesată acolo nu ar trebui să poată fi accesată:
confuzie şi greşeli
Scopul variabilelor tip instanţă > scopul variabilelor locale unei metode >
scopul variabilelor locale unui bloc de instrucţiuni
class C { class C {
int x; int x;
int y;
int z;
void m() { void m() {
y = 0; int y = 0;
for(z=0; z<10; z++) { for(int z=0; z<10; z++) {
y += z; y += z;
} } } } } }
IDP – Instrumente pentru Dezvoltarea Programelor 36
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Modificatori de acces
Pot fi folosiţi pentru controlul accesului
public:
bli
clasa/interfaţa pot fi accesate din afara pachetului
constructorii, metodele şi câmpurile pot fi accesate de oriunde poate fi accesată
clasa acestora
clasa acestora
protected:
pot fi accesate de alte clase din acelaşi pachet
şi din orice subclasă a clasei în care au fost declarate
ş
private: pot fi accesate numai din clasa în care au fost declarate
Fără modificator: pot fi accesate numai din pachetul în care sunt declarate
Dezavantaje:
Doar pentru grupuri pre‐definite
Drepturile de acces depind doar de cine (altă clasă) doreşte accesul, nu de cum
vor de fapt să folosească (e.g. doar 1 metodă)
IDP – Instrumente pentru Dezvoltarea Programelor 37
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Conceptul de interfaţă
Conceptul de interfaţă
Există diverse tipuri de interfeţe
Interfeţe utilizator
Interfeţe utilizator
Nu doar pentru software: orice instrument
Adesea pot suferi modificări,
câteodată nu au voie să sufere modificări
API
API‐uri: importante pentru programele ce le folosesc
i i t t t l l f l
Java interface: importante pentru clasele ce folosesc alte clase
prin intermediul lor
User/
Intenţia este întotdeauna aceeaşi: Client
Interfaţa defineşte şi restricţionează Interface
cum ajunge ceva să fie folosit
ajunge ceva să fie folosit
Utilizatorii/clienţii execută operaţii
numai prin intermediul interfeţelor Implementation
Dacă implementarea internă se modifică,
Dacă implementarea internă se modifică,
utilizatorii/clienţii nu trebuie să sufere modificări
IDP – Instrumente pentru Dezvoltarea Programelor 38
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
I
Interfeţe Java
f J
Modificatorii de acces pot doar controla accesul în funcţie de cine foloseşte
o clasă/metodă/câmp
o clasă/metodă/câmp
Folosind interfeţe putem restricţiona accesul într‐o manieră mai flexibilă:
O clasă poate implementa mai multe interfeţe
P tem folosi o altă interfaţă în f ncţie de
Putem folosi o altă interfaţă în funcţie de
•Cine o foloseşte (cu altă clasă) Client
•La ce este folosită Class
Totuşi:
Totuşi: adesea folosirea interfeţelor
adesea folosirea interfeţelor 1 2 3
vs. accesarea directă a unei clasă
reprezintă o decizie ce trebuie în Interface A
Interface B
prealabil cântărită
l bil â tă ită
Programatorii au nevoie să ştie că ar trebui
să folosească interfeţe Implementation
Programatorii au nevoie să ştie ce interfeţe
Programatorii au nevoie să ştie ce interfeţe Class
să folosească 1 or 2 or 3 ?
IDP – Instrumente pentru Dezvoltarea Programelor 39
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Exemple de interfeţe
Exemple de interfeţe
public class USSEnterprise
implements Maintenance, SafeControl, FullControl {
public void navigate(Point
p g dest) { … }
public void warpJump(Point dest) { … }
public int checkSystems() { … }
public void selfDestruct() { … }
}
interface Maintenance {
public int checkSystems();
}
interface SafeControl extends Maintenance {
public void navigate(Point
p g ( dest);
)
public void warpJump(Point dest);
}
interface FullControl extends SafeControl {
public void selfDestruct();
}
IDP – Instrumente pentru Dezvoltarea Programelor 40
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Exemple de interfeţe
Exemple de interfeţe
Scotty accesând sistemul:
Maintenance e = new USSEnterprise(); Accesul poate fi
i t status
int t t = e.checkSystems();
h kS t () restricţionat cu
succes doar prin
Spock accesând sistemul: accesarea de
SafeControl
S f C t l e = new USSEnterprise();
USSE t i () interfeţe
e.warpJump(new Point(103, 789)); corespunzătoare.
e.selfDestruct();
Nu compilează!!!
Se alege o interfaţă corespunzătoare pentru accesarea unei clase
Accesarea directă a unei clase poate duce la dependenţe şi alte greşeli ce ar fi
putut fi depistate de către compilator
IDP – Instrumente pentru Dezvoltarea Programelor 41
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Sumar
Modularitatea înseamnă că un sistem este compus din părţi
independente (module) având interfeţe bine‐definite
Poate fi atinsă prin “separation of concerns”
Regulă: “low coupling, high cohesion”
R lă “l li hi h h i ”
Ascunderea informaţiilor înseamnă că doar acele informaţii
absolut necesare pentru a face ceva este pusă la dispoziţie
absolut necesare pentru a face ceva este pusă la dispoziţie
Accesul este posibil prin interfeţe bine‐specificate
Detaliile
Detaliile interne de implementare sunt ascunse şi pot fi
interne de implementare sunt ascunse şi pot fi
modificate fără a afecta restul sistemului
IDP – Instrumente pentru Dezvoltarea Programelor 43
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
S
Sumar (
(partea a 2‐a)
2 )
JavaDoc
Formatarea Codului – Eclipse
Reflecţia
API‐ul Java Reflection
MetaJ
M t J
IDP – Instrumente pentru Dezvoltarea Programelor 44
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
JavaDoc
IDP – Instrumente pentru Dezvoltarea Programelor 45
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
J D
JavaDoc
Instrument ce generează documentaţie HTML pe baza codului sursă Java
Standard industrial pentru documentarea API
Standard industrial pentru documentarea API‐ului
ului Java
Java
Idea: dezvoltatorii adaugă comentarii speciale ce încep cu /** şi care conţin
informaţiile de documentare înaintea claselor, câmpurilor şi metodelor
Comentariile
Comentariile JavaDoc
JavaDoc sunt structurate folosind tag‐uri JavaDoc, care sunt
sunt structurate folosind tag uri JavaDoc care sunt
cuvinte cheie ce încep cu un semn @
/**
* Divides two integer numbers
* @author Christof Lutteroth
* @param x Dividend
* @@param y Di
Divisor
i
* @return x divided by y
* @throws ArithmeticException if y==0
*/
int div(int x, int y) { return x/y; }
IDP – Instrumente pentru Dezvoltarea Programelor 46
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
J D
JavaDoc şi Eclipse
i E li
Eclipse dispune de posibilitatea de auto‐
inserare de comentarii JavaDoc
1. Mutaţi cursorul pe poziţia dinaintea
tipului/metodei/câmpului
2. Tastaţi /** şi apăsaţi Enter
Generarea automată a documentaţiei
1. Din meniu: Project ‐> Generate Javadoc…
1 Din meniu: Project > Generate Javadoc
2. Se selectează locaţia executabilului
javadoc.exe
3. Se selectează folderul unde va fi salvată
documentaţia;
de obicei /doc în folderul proiectului
4. Se pot selecta opţiuni legate de formatarea
documentaţiei finale
documentaţiei finale…
5. Se face click pe finish
IDP – Instrumente pentru Dezvoltarea Programelor 48
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Vi li
Vizualizarea JavaDoc în Eclipse
J D î E li
1. În view‐ul JavaDoc atunci când sunt selectaţi identificatori prin double‐
click
2. În dialogul tip tooltip atunci când staţionăm cu cursorul mouse‐ului peste
identificator
3. ÎÎn view‐ul de ajutor în secţiunea "Java help“, atunci când cursorul este
poziţionat pe identificator
IDP – Instrumente pentru Dezvoltarea Programelor 49
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Instrumente de construcţie
Ex – Instrumentul ANT
IDP – Instrumente pentru Dezvoltarea Programelor 50
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
P
Procesul de construcţie
ld i
Generarea artefactelor pentru utilizatorii finali (programe
executabile, documentaţie, fişiere împachetate) pornind de la
bil d i fi i î h ) i dd l
artefactele dezvoltatorilor (codul sursă, modele, …)
Poate presupune mai mulţi paşi complexi
•Obţinerea ultimei versiuni stabile a codului sursă dintr‐un repository
•Obţinerea ultimei versiuni stabile a codului sursă dintr un repository VCS (e.g.
VCS (e g
SVN)
•Compilarea fişierelor conţinând codul sursă, linkarea acestora (e.g. javac)
•Rularea de teste (e.g. JUnit)
•Generarea de documentaţie (e.g. JavaDoc)
•Împachetarea (e.g. jar)
•Instalarea/deploy (e.g. copierea pachetelor pe un server remote folosind ftp)
•Curăţenia (e g Ştergerea fişierelor vechi sau redundante)
•Curăţenia (e.g. Ştergerea fişierelor vechi sau redundante)
În general sunt folosite procese de construcţie diferite pentru versiuni
diferite ale unui produs (e.g. vesiuni diferite de Linux enterprise, home şi
small business)
Procesele de construcţie pot fi automatizate folosind instrumente de
P l d t ţi t fi t ti t f l i d i t t d
construcţie
IDP – Instrumente pentru Dezvoltarea Programelor 51
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
I
Instrumente de construcţie
d i
Instrumentele de constucţie automatizează procesul de construcţie
Procesul de construcţie este documentat/specificat într‐un script de specificare a
ţ /p p p
procesului de construcţie (eng. build script)
Mai rapid decât construcţia manuală
Ajută la efectuarea aceloraşi construcţii de fiecare dată (mai puţine greşeli)
Pot
Pot fi folosite pentru gestiunea unor procese de construcţie dintre cele mai
fi folosite pentru gestiunea unor procese de construcţie dintre cele mai
diverse
Ajută la anularea defazajului dintre mediile de dezvoltare, integrare, testare şi
producţie
Orchestrarea
Orchestrarea procesului de construcţie; adesea sunt invocate alte
procesului de construcţie; adesea sunt invocate alte
instrumente pentru efectuarea paşilor de construcţie
Pot fi declanşate de alte instrumente, e.g. Pentru “nightly builds” sau
integrare continuă a produsului
.class
javac files
SVN .java
SVN files jar .jar
update
p .html
javadoc files
Exemplu de proces de construcţie
IDP – Instrumente pentru Dezvoltarea Programelor 52
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Target şi dependenţe
Target şi dependenţe
Diverşii paşi implicaţi în procesul de construcţie sunt numiţi targets (rezultatul unui pas de
construcţie este cunoscut sub denumirea de construirea unui target “building a target”)
Adesea există diverse dependenţe între target‐uri, e.g.
Obţinerea ultimei versiuni înaintea compilării codului sursă
Compilarea codului sursă înaintea împachetării
Target‐urile trebuie să fie construite respectând aceste dependenţe
Dependenţele target‐urilor
d l l sunt tranzitive
(dacă A→B şi B→C atunci A→C)
Procesul de construcţie poate fi optimizat prin executarea anumitor target‐uri numai dacă
acest lucru este absolut necesar (e.g. recompilarea claselor numai dacă fişierul.java s‐a
modificat)
difi t)
Exemplu: dependenţe între target‐uri într‐un proiect C++
calc
x→y = x depinde de y
main.o math.o
I
Instrumentul de construcţie ANT
ld i ANT
Instrument de scripting independent de platformă, open‐source pentru
automatizarea proceselor de construcţie
p ţ
Foloseşte fişiere XML pentru descrierea proceselor de construcţie şi a
dependenţelor între acestea (numele implicit al fişierului: build.xml)
Implementat în Java, având ca target principal folosirea împreună cu proiecte
Java standard de facto
Java; standard de facto
Rezolvă probleme de portabilitate ale altor instrumente de construcţie (e.g. make)
În cazul intrumentelor mai vechi acţiunile necesare pentru crearea unui target sunt
specificate conform unor comenzi shell specifice platformei
ANT furnizează funcţionalitate încorporată pentru construcţia multor task‐uri comune
proceselor de construcţie
Funcţiile încorporate sunt garantate a se comporta (aproape) identic pe orice platformă
de operare
Un script ANT defineşte un proiect având target‐uri
Target: set de task‐uri ce sunt executate
Task: bucată de cod ce poate fi executată
Când porniţi ANT puteţi selecta ce target(uri) sunt executate
Câ d iţi ANT t ţi l t t t( i) t t t
IDP – Instrumente pentru Dezvoltarea Programelor 54
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Proiecte
<project> reprezintă elementul de nivelul cel mai înalt; are trei atribute
opţionale:
name:
name: numele proiectului
numele proiectului
default: target‐ul default (când nu se alege nici un target de către utilizator)
basedir: directorul de bază pentru căi relative
Atributele unui <target>:
g
name: numele target‐ului (obligatoriu)
depends: listă de target‐uri de care poate depinde (opţional)
description: descrie scurtă a target‐ului (opţional)
În exemplu: A este executat primul, apoi B, apoi C şi în final D
<?xml version="1.0"?> D
<project name
name="DependencyDemo">
DependencyDemo >
<target name="A"/>
<target name="B" depends="A"/> B C
<target name="C" depends="A"/>
<target name="D" depends="B,C"/>
A
</project>
IDP – Instrumente pentru Dezvoltarea Programelor 55
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Task uri
Task‐uri
Task: bucată de cod ce poate fi executată şi care poate avea o serie de atribute
(argumente) şi sub‐tags
ANT încorporează peste 80 de task
ANT încorporează peste 80 de task‐uri
uri predefinite; multe altele disponibile
Adresarea unui task:
<name attribute1="value1" attribute2="value2" … />
<?xml version="1.0"?>
version="1 0"?>
<project name="Hello" default="compile">
<target name="compile" description="compile .java files">
<mkdir dir="classes"/>
<javac srcdir="
srcdir="."
" destdir="classes"/>
</target> <!-- This is an XML comment -->
<target name="jar" depends="compile"
description="create a jar file for the application">
<jar destfile="hello
destfile="hello.jar">
jar">
<fileset dir="classes" includes="**/*.class"/>
<manifest>
<attribute name="Main-Class" value="HelloProgram"/>
</manifest> </jar> </target>
</project>
IDP – Instrumente pentru Dezvoltarea Programelor 56
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
M i
Mai multe task‐uri
l k i
Task‐uri pentru fişiere: <copy file tofile>, <delete file>,
<mkdir dir>, <touch file>, <get src dest>
Task‐uri Java: <java classname>, <javac srcdir destdir>,
<javadoc sourcefiles destdir>, <junit …>
Împachetare: <jar destfile basedir>, <zip destfile
basedir>, <unzip src dest>
Alte task‐uri: <echo message>, <exec command>, <mail …>
Adăugarea propriilor task‐uri se face cu <taskdef
dăuga ea p op o tas u se ace cu tas de name a e c ass a e :
classname>:
…
public class MyOwnTask extends Task {
private String msg;
// setter for attribute "message"
public void setMessage(String msg) { this.msg = msg; }
public void execute() throws BuildException {
System out println(msg);
System.out.println(msg);
} }
IDP – Instrumente pentru Dezvoltarea Programelor 57
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Proprietăţi
Proprietate: nume case‐sensitive asociat cu o valoare
invariabil: odată setată nu mai poate fi modificată
poate fi folosită în specificarea valorilor unor atribute prin scrierea numelui proprietăţii între ${ şi
}
<property name="foo.x" value="bar"/> setează proprietatea foo.x la
valoarea bar (pentru fişiere: locaţie în loc de valoare)
Multe proprietăţi predefinite, e.g. basedir, ant.file, java.class.path,
p p ţ p , g , ,j p ,
os.name, os.version, file.separator
Target‐urile pot fi executate condiţional cu atribute speciale:
if: execuţia target‐ului doar dacă o anumită proprietate este setată
unless: execuţia target‐ului doar dacă o proprietate nu este setată
<?xml version="1.0"?>
<project name="MyProject">
<property name="classdir"
name= classdir location=
location="classes"/>
classes />
<target name="compile">
<javac srcdir="." destdir="${classdir}"/> </target>
<target name="workaround-code" if="system-has-bug"/>
<target name="normal-code" unless="system-has-bug"/>
</project>
IDP – Instrumente pentru Dezvoltarea Programelor 58
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
ANT şi Eclipse
ANT şi
1. Creaţi un fişier text build.xml în
folderul principal al proiectului
2. Deschideţi view‐ul Ant şi adăugaţi fişierul
de construcţie prin drag&drop în
i
interiorul view‐ului
i l i l i
3. Double‐click pe target pentru a‐l executa
IDP – Instrumente pentru Dezvoltarea Programelor 59
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
ANT B P
ANT Best Practices
i
1. Folosiţi Target‐uri Simple
ţ g p
Fiecare target ar trebui să execute o singură funcţionalitate bine definită
Target‐urile ce fac prea mult fac procesul de construcţie greu de întreţinut
şi ar trebui împărţite în mai multe target‐uri având dependenţe între ele
2. Standardizaţi Numele de Target‐uri
Sunt mai uşor de înţeles şi fac mai simplu procesul de folosire a mai
multor fişiere de construcţie
3. Folosiţi Proprietăţi pentru Configurabilitate
Proprietăţile ar trebui să fie definite pentru:
Orice informaţie ce trebuie configurată
Orice informaţie ce ar putea suferi modificări
Orice informaţie folosită în mai mult de un loc
4
4. Definiţi proprietăţile la începutul fişierului de build
Definiţi proprietăţile la începutul fişierului de build sau într
sau într‐un
un
fişier de proprietăţi separat, de sine stătător
IDP – Instrumente pentru Dezvoltarea Programelor 60
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Formatarea Codului Sursă
C d l iS ă
folosind Eclipse
You may not be able to read a
d
doctor's
' hhandwriting
d and
d
prescription, but you'll notice
his bills are neatly
typewritten
typewritten.
(Earl Wilson )
IDP – Instrumente pentru Dezvoltarea Programelor 61
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Arată / schimbă
profilul de stil de codare
Aplicarea profilului de stil de codare
editorului
dit l ip
prin
in sselectarea
l t codului
d l i
şi alegerea Source->Format
IDP – Instrumente pentru Dezvoltarea Programelor 62
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
IDP – Instrumente pentru Dezvoltarea Programelor 63
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Sumar
Instrumentele de documentare precum JavaDoc generează
documentaţie API pornind de la adnotările aferente codului
documentaţie API pornind de la adnotările aferente codului
sursă
Instrumentele de construcţie automatizează procesul de
construcţie
Gestiunea de configuraţii de construcţie diferite folosind scripturi de
construcţie
Task‐uri sunt bucăţi de cod de definesc ce se construieşte
Target‐urile definesc seturi de task‐uri ce sunt grupate logic împreună
Target urile pot depinde de alte target‐uri
Target‐urile pot depinde de alte target uri
Proprietăţile pot fi folosite pentru configurarea scriptului de construcţie
Formatarea codului sursă poate fi folosit pentru impunerea unui
p p p
stil de codare în mod automat
IDP – Instrumente pentru Dezvoltarea Programelor 64
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Reflecţia
IDP – Instrumente pentru Dezvoltarea Programelor 65
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
R fl i
Reflecţia
Abilitatea unui program de a observa şi posibil modifica
propria structură şi comportament.
i t t ă i t t
Două modalităţi de reflecţie
Structurală: reflecţia asupra structurilor de date & codului.
Structurală: reflecţia asupra structurilor de date & codului
Comportamentală: reflecţia asupra comportamentului
programului.
Două operaţii de bază
Introspecţia: observarea programului (eng. Introspection)
Intervenţia: modificarea acestuia (eng Intercession)
Intervenţia: modificarea acestuia (eng.
Poate fi statică (înaintea de runtime) sau dinamică (în
timpul runtime)
Poate fi periculoasă …
IDP – Instrumente pentru Dezvoltarea Programelor 66
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
P
Protocoale de MetaObiecte (MOPs)
l d M Obi (MOP )
Modalitatea prin care este realizată reflecţia în limbajele Orientate‐Obiect
Entităţile interne programului (e.g. tipuri) sunt reprezentate ca metaobiecte,
ţ p g ( g p ) p ,
ce sunt instanţe ale unor metaclase
Metaobiectele sunt similare obiectelor, dar servesc unui scop special
Modalitatea
Modalitatea de gestiune a acestor metaobiecte, spre exemplu modalitatea
de gestiune a acestor metaobiecte spre exemplu modalitatea
prin care metodele trebuie să fie apelate pentru a efectua un task de
reflecţie, reprezintă protocolul de metaobiecte
Introspecţia sistemului înseamnă obţinerea de metaobiecte
Intervenţia înseamnă că putem modifica obiectele iar respectivele modificări
vor afecta sistemul (uneori acest lucru este efectuat în mod automat)
Metaobjects
j
Program Internals
IDP – Instrumente pentru Dezvoltarea Programelor 67
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Introspecţia codului
Introspecţia codului
Suportată doar în câteva limbaje
Posibilitatea
Posibilitatea de a analiza corpurile metodelor şi vedea toate
de a analiza corpurile metodelor şi vedea toate
instrucţiunile
Codul programului este de obicei reprezentat sub forma arborilor
abstracţi de sintaxă (AST)
abstracţi de sintaxă
Metaclase pentru diverse instrucţiuni, expresii, …
class Foo { Object f = new Foo();
int inc(int x) { M th d m = f
Method f.getClass()
tCl ()
return x + 1; .getMethod("inc");
} } Statement[] stmts =
m.getBody();
Variable Metaobiecte
name = “x”
Plus Return Statement[]
expr1
1 expr element
l t0
IntConstant
expr2
value = 1
IDP – Instrumente pentru Dezvoltarea Programelor 69
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Intervenţia
Structurile de date / codul programului pot fi modificate la runtime
Se poate, de exemplu, prin simpla modificare a meta‐obiectelor
Se poate de exemplu prin simpla modificare a meta obiectelor
Mecanism rar ‐ poate induce un grad de pericol (confuzie şi nesiguranţă)
Invarianţi
Invarianţi precum tipuri şi codul programului sunt importanţi pentru înţelegerea
precum tipuri şi codul programului sunt importanţi pentru înţelegerea
unor sisteme complexe Înainte
class Foo {
Pseudo-cod int inc(int x) {
Obj t f = new F
Object Foo();
()
return x+1;
Method m = f.getClass()
} }
.getMethod("inc");
Statement[] stmts = m.getBody(); După
Return rstmt = (Return) stmts[0]; class Foo {
Plus pexpr = (Plus) rstmt.expr; int inc(int x) {
pexpr.expr2 = new IntConstant(99); return x+99;
} }
IDP – Instrumente pentru Dezvoltarea Programelor 70
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Java Reflection API
IDP – Instrumente pentru Dezvoltarea Programelor 71
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
R fl i î J
Reflecţia în Java
Java nu suportă în întregime conceptul de reflecţie dinamică
Doar anumit grad de reflecţie
Introspecţia tipurilor
Introspecţia semnăturilor de metode
Introspecţia accesului la tipuri şi metode
•Instanţiere
I i
•Accesul la câmpuri
•Invocarea metodelor
•Invocarea metodelor
Pentru siguranţă: când ceva nu funcţionează sunt aruncate excepţii
g p
((e.g. NoSuchFieldException, NoSuchMethodException,
, p ,
SecurityException)
IDP – Instrumente pentru Dezvoltarea Programelor 72
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Când
â d avem nevoie de reflecție?
d fl ?
În programele “normale” cel mai adesea nu veți avea nevoie de
reflecție… Totuși
Aveți nevoie de reflecție dacă dezvoltați programe ce
procesează alte programe (module, componente, plug‐ins,
servicii, etc).
Exemple tipice:
Un container Web (Tomcat, JBoss)
Un program ce încarcă plug‐in‐uri (Eclipse)
Un program pentru testarea automată a temelor
IDP – Instrumente pentru Dezvoltarea Programelor 73
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Clasa Class
l l
Pentru a obține metaobiectul ce descriu o clasă puteți:
Dacă dețineți instanța/obiectul obj, puteți obține obiectul
Class din
Class c = obj.getClass();
Puteți obține obiectul Class ce descrie o superclasă a clasei c
prin
Class supp = c.getSuperclass();
g p ();
Dacă cunoașteți numele clasei (ex, Button) la compilare,
puteți obține obiectul Class prin
Class c = Button.class;
Button class;
Dacă cunoașteți numele clasei la run‐time puteți obține
obiectul Class prin
Class c = class.forName(str);
class forName(str);
IDP – Instrumente pentru Dezvoltarea Programelor 74
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Funcționează?
Nu întotdeauna:
Doar dacă ClassLoader‐ul cunoaște clasa respectivă
Altfel se aruncă ClassNotFoundException
lf l ă l
Soluția pentru încărcarea dinamică a claselor constă în folosirea
propriului ClassLoader
propriului ClassLoader
IDP – Instrumente pentru Dezvoltarea Programelor 75
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
import java.io.File;
import java.net.URL; Exemplu de încărcare a unei
import java.net.URLClassLoader;
class MyClass{
clase:
public String myMethod() {
return "a message";
}
}
URL[] urls
l = null;
ll
IDP – Instrumente pentru Dezvoltarea Programelor 76
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
URL class loader
l l d
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
Object ob = c.newInstance();
Class arg2[] = {};
Method m2 = c.getMethod(
c getMethod("tt"
tt , arg2);
m2.invoke(ob, null);
IDP – Instrumente pentru Dezvoltarea Programelor 77
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
}
}
}
IDP – Instrumente pentru Dezvoltarea Programelor 78
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Obținerea numelui clasei încărcată
Dacă aveți un obiect clasă c, puteți obține numele clasei din care
a fost acesta încărcat folosind c.getName()
getName întoarce numele întreg, de ex:
Class c = Button.class;
String s = c.getName();
System.out.println(s);
va afișa
ș
java.awt.Button
IDP – Instrumente pentru Dezvoltarea Programelor 79
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Obținerea superclaselor
b l l
Obținerea modificatorilor
b df l
Modificatorii (public, final, abstract etc.) unui obiect Class sunt
codificați în interiorul unui int și pot fi interogați prin metoda
getModifiers().
getModifiers()
Pentru decodificarea rezultatului int se folosesc metodele ale
clasei Modifier:
clasei Modifier:
import java.lang.reflect.*;
Exemplu:
p
if (Modifier.isPublic(m))
System.out.println("public");
IDP – Instrumente pentru Dezvoltarea Programelor 81
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Obținerea modificatorilor
b df l
Modifier conține metode precum:
conține metode precum:
public static boolean isAbstract(int)
p
public static boolean isFinal(int)
( )
public static boolean isInterface(int)
public static boolean isPrivate(int)
bli static
public i boolean
b l i P
isProtected(int)
d(i )
public static boolean isPublic(int)
p
public static String
g toString(int)
g( )
•Această metodă întoarce un string de forma
"public final synchronized strictfp"
IDP – Instrumente pentru Dezvoltarea Programelor 82
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Obținerea interfețelor
b f l
O clasă poate implementa zero sau mai multe interfețe
O clasă poate implementa zero sau mai multe interfețe
getInterfaces() întoarce un array de obiecte Class.
Exemplu:
static void printInterfaceNames(Object o) {
Class
ass c = o.g
o.getClass();
t ass();
Class[] theInterfaces = c.getInterfaces();
for (Class inf: interfaces) {
System.out.println(inf.getName());
}
}
IDP – Instrumente pentru Dezvoltarea Programelor 83
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Obținerea câmpurilor
b â l
public Field[] getFields() throws SecurityException
Întoarce un array de obiecte public Fields (inclusiv câmpurile
moștenite).
Lungimea acestui array poate fi zero
Câmpurile nu sunt întoarse într‐o anumită ordine
Nu sunt întoarse variabile statice.
IDP – Instrumente pentru Dezvoltarea Programelor 84
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Obținerea Constructorilor unei clase
b l l
Dacă c este un obiect Class, atunci
este un obiect Class atunci
c.getConstructors() : Constructor[] întoarce un array al constructorilor
publici ai clasei c.
c.getConstructor( Class … paramTypes ) întoarce un contructor
corespunzător tipurilor de parametrii ce se potrivesc argumentelor.
Ex:
String.class.getConstructors().length
> 15;
String.class.getConstrucor( char[].class, int.class, int.class).toString()
> String(char[], int,int).
IDP – Instrumente pentru Dezvoltarea Programelor 85
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Constructori
Dacă c este un obiect Constructor, atunci
c.getName() întoarce numele constructorului
c.getDeclaringClass() întoarce obiectul Class în care a fost declarat
c.getModifiers() întoarce modificatorii Modifiers ai constructorului
c.getParameterTypes() întoarce un array de obiecte Class în ordinea declarării
acestora
c.newInstance(Object… initargs) crează și întoarce o nouă instanță a clasei c
IDP – Instrumente pentru Dezvoltarea Programelor 86
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Exemplu
l
Constructor c = String.class.getConstrucor( char[].class, int.class,
int.class).toString()
St i ( h [] i t i t)
String(char[], int,int).
String s = c.newInstance(
new char[] {‘a’,’b’,’c’,’d’ }, 1, 2 );
assert s.equals(“bc”);
IDP – Instrumente pentru Dezvoltarea Programelor 87
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Metode
d
IDP – Instrumente pentru Dezvoltarea Programelor 88
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Array
Pentru a afla tipul componentelor unui array,
c.getComponentType()
•Întoarce null dacă c nu este clasa unui array
Exemplu:
int[].class.isArray() == true ;
int[].class.getComponentType() == int.class
IDP – Instrumente pentru Dezvoltarea Programelor 90
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Array
Clasa Arrayy furniează metode statice p
pentru invocarea array‐
y
urilor
De exemplu, pentru crearea unui array
Array.newInstance(Class componentType, int size)
, j ,
Această metodă întoarce, ca Object, noul array
y
Obiectul componentType poate fi un alt array
•Aceasta ar putea conduce la crearea unui array multi‐dimensional
Exemple
l
Următoarele două obiecte sunt de același tip:
new String[10]
new String[10]
Array.newInstance(String.class, 10)
Următoarele două obiecte sunt de asemenea de același tip:
U ăt l d ă bi t td d l i ti
new String[10][20]
Array.newInstance(String.class, 10, 20)
A I (S i l 10 20)
IDP – Instrumente pentru Dezvoltarea Programelor 92
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Array
Pentru a obține valoarea elementelor unui array,
ț y
Array.get(Object array, int index) întoarce un Object
Array.getBoolean(Object array, int index) întoarce un
b l
boolean
Array.getByte(Object array, int index) întoarce un byte
etc
etc.
Pentru stocarea unei valori într‐un array,
Array.set(Object array, int index, Object value)
Array.set(Object
Array.setInt(Object array, int index, int i)
Array.setFloat(Object array, int index, float f)
etc.
IDP – Instrumente pentru Dezvoltarea Programelor 93
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Exemple
l
IDP – Instrumente pentru Dezvoltarea Programelor 94
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Exemple
l
String.class.getConstructors().length
> 15
String.class.getDeclaredConstructors().length
String class getDeclaredConstructors() length
> 16.
Constructor[] cs
C t t [] = String.class.getDeclaredConstructors();
St i l tD l dC t t ()
for(Constructor c : cs)
if( ! (Modifier.isPublic(c.getModifiers())))
out.println(c);
> java.lang.String(int,int,char[]) // package
IDP – Instrumente pentru Dezvoltarea Programelor 96
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
IDP – Instrumente pentru Dezvoltarea Programelor 97
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Exemplu de reflecţie în Java: Acces bazat pe
Exemplu de reflecţie în Java: Acces bazat pe
introspecţie (1)
public class Foo {
public
bli void
id hello()
h ll () {
System.out.println("hello!");
} }
import java.lang.reflect.*;
Exemplu de reflecţie în Java: Acces bazat pe
Exemplu de reflecţie în Java: Acces bazat pe
introspecţie (2)
public class Foo { public int x; }
import java.lang.reflect.*;
Cl
Clasa Class<T>
l
static Class<?> forName(String className)
String getName()
String getSimpleName()
Class<? super T> getSuperclass()
Field[] getDeclaredFields()
Field[] getFields()
Field getDeclaredField(String name)
Field getField(String name)
Constructor<T> getConstructor(Class... paramTypes)
Method getMethod(String name, Class... paramTypes)
T newInstance()
boolean isArray()
boolean isInterface()
boolean isPrimitive()
Cl
Clasa i ld şi Clasa Method
Field i Cl h d
Class Field
String getName()
Class<?> getType()
Object
Object get(Object obj)
int getInt(Object obj)
boolean getBoolean(Object obj)
void set(Object obj,
obj Object value)
Class Method
String getName()
Class<?>[] getParameterTypes()
Class<?>
Class<?> getReturnType()
Object invoke(Object obj, Object... args)
IDP – Instrumente pentru Dezvoltarea Programelor 101
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Accesarea câmpurilor
â l private
public class Secret {
private
pr ate Str
String
ng secretCode
secret ode = "It's
t s a secret";
secret ;
private String getSecretCode(){
return secretCode;
} import java.lang.reflect.Field;
import java.lang.reflect.Method;
}
public class Hacker {
private static final Object[] EMPTY = {};
public void reflect() throws Exception {
Secret instance = new Secret();
Class secretClass = instance.getClass();
// Print all the method names & execution result
Method methods[] = secretClass.getDeclaredMethods();
S stem o t println("Access all the methods")
System.out.println("Access methods");
for (int i = 0; i < methods.length; i++) {
System.out.println("Method Name: " + methods[i].getName());
System.out.println("Return type: " + methods[i].getReturnType());
methods[i].setAccessible(true);
[] ( )
System.out.println(methods[i].invoke(instance, EMPTY) + "\n");
}
Accesarea câmpurilor
â l private
public class Secret {
private String secretCode = "It's a secret";
private String getSecretCode(){
return secretCode;
// Print all the field names & values
} Field fields[] = secretClass.getDeclaredFields();
} System.out.println("Access all the fields");
for (int i = 0; i < fields.length; i++){
System.out.println("Field Name: " + fields[i].getName());
fields[i].setAccessible(true);
System.out.println(fields[i].get(instance) + "\n");
\n );
}
}
MetaJ
http://www.emn.fr/z-info/sudholt/research/metaj/
M J
MetaJ
Interpretor reflectiv pentru limbaje tip Java
p p j p
Prototip de cercetare scris de Rémi Douence şi Mario
Südholt
p // / / / /
http://www.emn.fr/x‐info/sudholt/research/metaj/ j/
Oferă reflecţie completă dinamică structurală &
comportamentală: se pot modifica clase, cod şi chiar şi
interpretorul
Cu alte cuvinte: aproape orice poate fi modificat de către un
program
Totuşi: dacă modificaţi lucrul incorect puteţi uşor ajunge la
crash
Problema comună limbajelor reflective:
Problema comună limbajelor reflective:
balansarea între putere şi siguranţă
IDP – Instrumente pentru Dezvoltarea Programelor 105
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Exemplu: Reflecţie Dinamică cu MetaJ
class Pair { String fst; String snd; }
M
Metaclasele din MetaJ
l l di M J
class Class {
Class extendsLink; // superclasa
DataList dataList; // lista de câmpuri
MethodList methodList;
Instance instantiate() { ... } // operatorul “new“
}
class Method {
private StringList args; // numele parametrilor
private Exp body; // corpul metodei
Data apply(Environment
l ( i argsE, Instance i) {
...
return this.body.eval(argsE); In plus față de Java…
}
}
P bl
Probleme de siguranţă
d i ă
class Pair {
g fst; String
String g snd;
String toString() {
return "(" + fst + ", " + snd + ")";
} }
class NotAPair {
int fst;
}
class Main {
void main() {
Pair p = new Pair("1", "2");
Instance metaPair = reify(p);
metaPair.instanceLink = NotAPair;
p.fst = 99;
y p (p g())
System.out.println(p.toString());
} }
R fl i C
Reflecţie Comportamentală
lă
Nu doar programul ce rulează poate fi modificat (reflecţie structurală), dar şi
( ţ p )
sistemul de rulare (reflecţie comportamentală)
În MetaJ: chiar interpretorul poate fi modificat
Meta‐arhitectură tip "Reflective Towers"
Interpretorul de bază ce interpretează programul nu se modifică
I t t ld b ă i t t ă l difi ă
Posibilitatea inserării unui nou interpretor intermediar între interpretorul de bază
şi program
Interpretorul intermediar poate
p p
fi modificat arbitrar folosind Program
reflecţia (precum programul)
Posibilitatea modificării semanticii Intermediate Interpreter
operaţionale a limbajului
p ţ j
Interpretorul de bază interpretează
…
interpretorul intermediar de deasupra Intermediate Interpreter
care la rândul să interpretează
programul
p g
B
Base Interpreter
I t t
Putem insera oricâte interpretoare
intermediare (turn de interpretoare)
IDP – Instrumente pentru Dezvoltarea Programelor 109
Platformă de e‐learning și curriculă e‐content pentru
învățământul superior tehnic
Sumar
Reflecţia
Reflecţia reprezintă abilitatea unui program de a observa şi
reprezintă abilitatea unui program de a observa şi
posibil modifica propria structură şi comportament
Introspecţia şi intervenţia
Limbajele OO folosesc protocoale de metaobiecte (MOPs) cu
metaclase şi metaobiecte
Java suportă doar anumite facilităţi de acces introspectiv la
metode şi câmpuri
Alte limbaje (e.g. MetaJ) oferă reflecţie totală
Al li b j ( M J) f ă fl i lă
Totuşi: reflecţia poate fi periculoasă