Sunteți pe pagina 1din 14

Programare Orientată pe Aspecte în Java

CAPITOLUL II

PROGRAMARE ORIENTATĂ PE ASPECTE ÎN JAVA

2.1 Introducere în Programarea Orientată pe Aspecte

Programarea orientată pe aspecte este o nouă tehnologie promiţătoare pentru


a separa concernurile crosscutting care sunt de obicei greu de rulat în programarea
orientată pe obiecte.
Astăzi programarea orientată pe obiect (OOP) este începutul curentului bazat
pe paradigma programelor unde problemele reale sunt descompunerea în obiecte a
componentelor abstracte şi a datelor într-un singur unit.
OOP încurajează reutilizarea software-ului care furnizează design şi a
limbajelor construite pentru modularitate, încapsulare, moştenire şi polimorfism. Deşi
OOP a avut un mare success în modelarea şi implementarea sistemelor software
complexe, sunt şi probleme. Practic experienţa cu proiectele mari şi acele programe
au probleme legate de mentenanţa codului datorită separării lor în module. O ]
ncercare de a face o schimbare minoră în design-ul programului poate avea nevoie de
multe update-uri la un număr mare de module irelevante.
În proiectarea oricărui sistem în timp real, primul pas constă în stabilirea
funcţionalităţilor sale plecând de la probleme concrete pe care acesta trebuie să le
rezolve. În raport de modul în care va fi implementată, o functionalitate poate fi:
- core concern  care poate fi implementată într-un singur modul
- crosscutting concern  care nu poate fi implementată într-un singur modul.
Programarea Orientată pe Aspecte (AOP) este o nouă tehnologie pentru
separarea crosscutting concern-urilor într-un singur unit apelând aspectul. Astfel se
pot implementa separat core concern-urile folosind programarea orientate pe

9
Programare Orientată pe Aspecte în Java

obiecte, de crosscutting concern-uri care vor fi implementate utilizând programarea


orientată pe aspecte.
Un aspect este un unit modular de implementare a crosscutting. El
încapsulează acel efect de clase muliple aflate în module reutilizabile. Cu AOP, se
începe implementarea proiectelor noastre utilizând limbaje orientate pe obiecte (de
exemplu Java) şi atunci se tratează separat implicaţia crosscutting, în cod ce
implementează aspectele. În cele din urmă, codul şi aspectele sunt combinate într-o
execuţie finală utilizând aspect Weaver (compunere). Va rezulta un singur aspect
care poate contribui la implementarea unui număr de metode, module sau obiecte,
crescând atât reutilizarea cât şi mentenanţa codului. Figura 1 explică procesul de
compunere.
Se notează acel cod original despre care este nevoie să se ştie vreo
funcţionalitate, aspectul se adaugă, se recompilează direct fără aspect, respectând
funcţionalitatea originală.

Figura 1. Aspect Weaver

10
Programare Orientată pe Aspecte în Java

Programarea Orientată pe Aspecte completează Programarea Orientată pe


Obiecte, nu o înlocuie, facilitează alte tipuri de modularitate care lucrează.
În procesul de implementare a unei aplicaţii, modularitatea se poate pierde într-
una din următoarele situaţii:
- implementarea mai multor funcţionalităţi într-un singur modul care va duce la
apariţia unui cod încurcat (code tangling) ce va afecta, aproape sigur
funcţionalitatea principală a modulului respectiv.
- Implementatrea unei funcţionalităţi în mai multe module care va duce la apariţia
unui cod împrăştiat (code scattering) care va fi greu depanat, întreţinut sau
dezvoltat ulterior. În acest caz pot apărea două subcazuri:
- existenţa unor blocuri de cod asemănătoare în mai multe module, ceea ce
îngreunează foarte mult atât depanarea cât şi modificarea ulterioară a aplicaţiei
- existenţa unor blocuri de cod complementare în mai multe module, ceea ce
îngreunează urmărirea coduluipai eu ma duc la ore de la 13
chiar din faza iniţială a scrierii sale.

11
Programare Orientată pe Aspecte în Java

Fazele elaborării unei aplicaţii folosind programarea orientată pe aspecte:

- analiza funcţionalităţilor care trebuie să le ofere aplicaţia şi separarea acestora


în core concern-uri şi crosscutting concern-uri
- implementarea independentă a tuturor funcţionalităţilor sub forma unor module
sau sub forma unor aspecte
- stabilirea regulilor după care trebuie asamblate modulele şi aspectele în vederea
obţinerii aplicaţiei finale

Figura 2. Fazele unei aplicaţii

Programarea Orientată pe Aspecte este un concept, el nu limitează specificul


limbajului de programare. În fapt el poate ajuta toate limbajele care nu sunt direct
orientate pe obiecte prin acele utilizări sigure, ierarhic repartizate.
Programarea Orientată pe Aspecte poate fi implementată în diferite limbaje de
programare precum C++, C, C#, Java.
Programarea Orientată pe Aspecte în Java conţine:
- AspectJ
- AspectWerz

12
Programare Orientată pe Aspecte în Java

- Hyper J
- JAC
- Jmangler
- AcrchJava

AspectJ este o extensie a limbajului Java lansată în anul 1998 de către o echipă
de cercetători de la Xerox Palo Alto Research Center condusă de Cristina Lopes şi
Gregor Kicyales care implementează conceptele programării orientate pe aspecte
folosind limbajul Java. Orice program corect scris în limbajul Java este şi un
program valid în AspectJ.

2.2 Concepte ale limbajului AspectJ

Moştenirea, polimorfismul şi încapsularea din programarea orientată pe obiecte


au corespondent în programarea orientată pe aspecte pe JOIN POINT, POINTCUT,
IMPLEMENTATION şi ADVICE.
Rolul limbajului AspectJ este de a asambla modulele aplicaţiei conform unor
reguli. În limbajul AspectJ implementarea regulior de validare de către compilator se
numeşte crosscutting.
Crosscutting-ul poate fi:
- crosscutting dinamic care modifică fluxul iniţial al aplicaţiei prin modificarea
sau adăugarea unor anumite acţiuni
- crosscutting static care modifică structura statică a aplicaţiei (clase, interfeţe,
aspecte), fără a intevenii în fluxul său
Crosscutting-ul poate intevenii în execuţia unui program doar în anumite puncte
numite join-point-uri.
Un join-point poate fi stabilit în unul din momentele următoare ale execuţiei unui
program:
- apelul unui constructor sau al unei metode
- execuţia unui constructor sau a unei metode
- modificarea valorii unui câmp

13
Programare Orientată pe Aspecte în Java

- apariţia unei excepţii


Join-point-urile sunt selectate folosind o construcţie sintactică a limbajului numită
pointcut.
Cu ajutorul pointcut-ului se indică tipul şi antetul unui join-point. Folosind un
pointcut se pot obţine informaţii despre contextul în care a fost apelată o anumită
metodă.
Codul care se execută atunci când execuţia unui program ajunge la un anumit
join-point se numeşte advice. Un advice poate fi executat înaintea sau după întâlnirea
unui join-point sau în timpul execuţiei sale.
Modificarea statică a structurii unei clase sau interfete, respectiv a unui aspect
se realizează folosind un tip special de declaraţii numit inter-type declaration. Cu
ajutorul unor declaraţii de tipul compile-time declaration se pot adăuga mesaje sau
erori care să fie afişate sau semnalate în timpul compilări.
Conceptul fundamental al Limbajului AspectJ este aspectul.

2.2.1 Declararea unui Aspect

Declararea unui aspect se face în acelaşi mod în care se defineşte o clasă în


Java. Un aspect poate să aibă variabile sau metode membre dar si elemete de tipul
celor anterior prezentate.
Declararea unui aspect se realizează astfel:
public aspect <numeaspect>

14
Programare Orientată pe Aspecte în Java

2.2.2 Declararea unui pointcut

Un pointcut poate să aibă nume sau poate fi anonim.


Declararea unui pointcut anonim este cel din exemplul următor:
public aspect Aspect1{
void around(String sir):call(*Afisare (String))&&args(sir)
{//poincut anonim
proceed(“Salut”+sir);
}
}
Declararea unui pointcut cu nume se realizează folosind sintaxa:
[specificatori acces] pointcut nume([parametrii]) : definiţie
Pentru un pointcut se pot indica restrictii de acces, folosind specificatorii: public,
private, protected.
Definiţia unui pointcut trebuie să conţină atât numele entităţilor care trebuie
urmărite, cât şi momentul din program în care trebuie capturate.
Numele şi tipul entităţilor se poate indica direct sau prin şabloane folosind
wildcard-urile:
- * indică oricâte caractere mai puţin caracterul punct(.)
- .. indică oricăte caractere inclusiv caracterul punct (.)
- + indică orice subclasă sau subinterfaţă a unui anumit tip
Se mai pot utiliza şi operatorii logici de conjuncţie (| |), disjuncţie (&&) sau
negaţie (!).

15
Programare Orientată pe Aspecte în Java

2.2.3 Sintaxa unui Advice

Un advice este o unitate lexicală a unei metode asemănătoare unei metode


care permite indicarea acţiunilor care trebuie efectuate în join-poin-urile capturate de
către un pointcut.
Sintaxa unui advice este:
tip_advice[ throws eroare]:pointcut
{
instructiuni
}
Tipul unui advice reprezintă momentul în care acesta va fi executat raportat la
capturarea unui join-point. Tipul advice-ului se indică folosind specificatorii :

- before (parametri) se execută înaintea unui join-point

- after(parametri) returning[(parametrii)] se execută după


încheierea normală a execuţiei unui join-point, iar valoarea returnată poate fi
accesată prin intermediul parametrilor
- after(parametri) trowing se execută după încheierea forţată a execuţiei
unui join-point datorită apariţiei unei excepţii, iar excepţia apărută poate fi
accesată prin intermediul parametrilor
- after (parametri) se execută după incheierea execuţiei unui join-point,
indiferent de modul în care aceasta s-a încheiat
- tip around (parametri) se execută în jurul unui anumit join-point
Pentru ca în interiorul unui advice să fie executată operaţia dintr-un join-point
capturat trebuie folosit cuvântul cheie procced(), altfel execuţia acelei operaţii

va fi ocolită.

16
Programare Orientată pe Aspecte în Java

2.3 Aplicaţie

Pentru a înţelege mai bine conceptele limbajului AspectJ se consideră un


exemplu simplu:
class TestClass{
public static void sayHello(){
System.out.println("Hello, AOP");
}
public static void sayAnyThing(String s){
System.out.println(s);
}
public static void main(String[] args){
sayHello();
String p="ok";
sayAnyThing(p);
}
}

Acum există codul Java pentru TestClass.java.

Se presupune că se doreşte utilizarea aspectelor care să realizeze modicările:


1) Să se tipărească un mesaj înainte şi după orice apel al metodei
TestClass.sayHello()
2) Este necesar un test pentru ca argumentul din metoda
TestClass.sayAnyThing() să fie format din cel puţin trei caractere
Implementarea aspectului:
1: public aspect MyAspect{
2: public pointcut sayMethodCall():call(public void
TestClass.say*());

17
Programare Orientată pe Aspecte în Java

3: public pointcut sayMethodCallArg(String str):call(public


void TestClass.sayAnyThing(String)) &&args(str);
4: before():sayMethodCall(){
5: System.out.println("\n TestClass." +
+thisJoinPointStaticPart.getSignature().getName()+"start...");
6: }
7: after():sayMethodCall(){
8: System.out.println("\n TestClass."+
+thisJoinPointStaticPart.getSignature().getName()+"end...");
9: }
10: before(String str):sayMethodCallArg(str){
11: if(str.length()<3){
12: System.out.println("Eroare: nu poti introduce cuvinte de
lungime mai mica de 3 caractere");
13: return;
14: }
15: }
16:}
Linia 1 defineşte aspectul.
În liniile 2 şi 3 se specifică locul unde se modifică codul din TestClass. Se
definesc două point-cut-uri, două join-point-uri: apelul metodelor sayHello şi
sayAnyThing din clasa TestClass.
Poincut este o construcţie a limbajului prin culegerea ieşirilor unui set de join-
point bazat pe criteriul definit. Criteriul poate fi numele explicit al funcţiei sau numele
funcţiei specificat de wildcard.
public pointcut sayMethodCall():call(public void
TestClass.say*());
În linia anterioară s-a definit un pointcut numit sayMethodCalll care conţine
acele legături de ieşire a oricărui apel al metodei TestClass.sayHello(). În
plus, ea leagă ieşirea oricărei metode publice din TestClass cu zero argumente şi
al căror nume începe cu „say”.

18
Programare Orientată pe Aspecte în Java

Pointcut este utilizat prin definirea advise-ului. În exemplul prezentat, liniile 4-6
şi 7-9 definesc două advice-uri care se vor executa înaintea şi după primul pointcut.
La final, în liniile 10-15 se imlementează un advice pentru al doilea pointcut şi
se utilizează un set de precondiţii înainte de execuţia metodei
TestClass.sayAnyThing().

Atunci când pointcut şi advice influenţează execuţia statică a programului,


introduction permite aspectului modificarea structurii programului. Utilizând
introduction, aspectul poate adăuga noi metode şi variabile clasei, declara o clasă
implementând o interfaţă.

Compilare

Iniţial se downloadează versiunea recentă de AspectJ, apoi se compilează şi


se rulează exemplul anterior astfel:
ajc MyAspect.aj TestClass.java
java TestClass

19
Programare Orientată pe Aspecte în Java

2.4 Prioritatea aspectelor

Într-un program este posibil să existe advise-uri aflate în aspecte diferite care
să acţioneze asupra aceluiaşi join-point. În acest caz este necesar să se stabilească
ordinea în care acestea se vor executa.
Se consideră clasa Casa care conţine două metode care simulează intrarea şi
ieşirea din casă:
public class Casa{
void intrare(){
System.ot.println(“Intrare in casa”);
}
void iesire(){
System.out.println(“Iesire din casa”);
}
}
Se adaugă un aspect numit AspectLumini care simulează stingerea becurilor
înainte de intrarea în casă şi aprinderea becurilor după intrarea în casă:
public aspect AspectLumini{
after() : call (void Casa.intrare()){
System.out.println(“aprindere lumina”);
}
before() : call (void Casa.iesire()){
System.out.println(“stingere lumina”);
}
}
Se mai adaugă un aspect numit AspectAlarma care simulează activarea alarmei
înainte de ieşirea din casă şi dezactivarea alarmei după intrarea în casă:
public aspect Aspect Alarma{
after() : call (void Casa.intrare()){
System.out.println(“dezactivare alarma”);

20
Programare Orientată pe Aspecte în Java

}
before() : call (void Casa.iesire()){
System.out.println(“activare alarma”);
}
}
Clasa test:
public class Test{
public static void main (String[] args){
Casa casa=new Casa();
casa.intrare();
casa.iesire();
}
}
Rezultatul obţinut în urma rulării este:
intrare in casa
dezactivare alarma
aprindere lumina
stingere lumina
activare alarma
iesire din casa
Se observă că advice-urile din aspectul AspectAlarma au fost executate
înaintea celor din AspectLumini, ceea ce înseamnă că primul aspect a avut
prioritate mai mare decât al doilea. Recomandabil este invers, operaţiile de
activare/dezactivare să fie executate cu lumina aprinsă, ceea ce ar însemna
stabilirea unor priorităţi mai mari aspectului AspectLumini faţă de aspectul
AspectAlarma.
Stabilirea unor priorităţi crescătoare pentru mai multe aspecte se realizează
folosind următoarea construcţie sintactică, în cadrul unui aspect separat:
declare precedence : aspect_1, aspect_2,..., aspect_n;
În exemplul de mai sus trebuie sa mai adăugăm şi aspectul Prioritate:
Public aspect Prioritate{
Declare precedence: AspectAlarma, AspectLumini;

21
Programare Orientată pe Aspecte în Java

22

S-ar putea să vă placă și