programmazione orientata agli aspettihomes.di.unimi.it/~belletc/corsi/is2004/aop.pdfprogrammazione...
TRANSCRIPT
Programmazione orientata agli Programmazione orientata agli aspettiaspetti
Mattia Monga
Dipartimento di Informatica e Comunicazione
Università degli Studi di Milano
Ingegneria del software, 17 maggio 20042
Universitas Mediolanensi
s
Idee chiare e distinteIdee chiare e distinte
• Soluzione di un problema– Scomposizione in elementi più semplici
(analisi )– Ricomposizione della soluzione finale ( sintesi )
“Secondo precetto: dividere ciascuna delle difficoltà da esaminare nelle parti di cui è
suscettibile e di cui c‘è bisogno per meglio risolverla.”
Cartesio [Discorso sul Metodo]
Ingegneria del software, 17 maggio 20043
Universitas Mediolanensi
s
Divide et imperaDivide et impera
• Nello sviluppo del software il principio è applicato in tutte le fasi– l'analisi dei requisiti, il progetto, la
realizzazione, la convalida, la messa in opera.
– Fondamentale per la suddivisione del lavoro e delle responsabilità
Ingegneria del software, 17 maggio 20044
Universitas Mediolanensi
s
L’analisi non è sempre gerarchicaL’analisi non è sempre gerarchica
• Ogni persona coinvolta a qualche titolo nel sistema (dagli investitori fino agli utenti finali) ragiona attraverso l'uso di una opportuna astrazione , secondo i propri obiettivi. – Tutt’altro che indipendenti– Non sempre aggregabili
gerarchicamente– Sovrapposizioni e incongruenze
Ingegneria del software, 17 maggio 20045
Universitas Mediolanensi
s
Il punto di vista dei programmatoriIl punto di vista dei programmatori
• Tradizionalmente: decomposizione secondo le funzionalità del sistema– Alcune problematiche risultano
trasversali!• Sicurezza
• Concorrenza
• Localizzazione
• …
Ingegneria del software, 17 maggio 20046
Universitas Mediolanensi
s
L’eco della “spaghetti L’eco della “spaghetti programming”programming”
•Code Tanglingun componente contiene codice che si riferisce a diverse problematiche•Code Scatteringil codice che si riferisce ad una problematica risulta disperso fra più componenti.
Ingegneria del software, 17 maggio 20047
Universitas Mediolanensi
s
Programmi monoliticiProgrammi monolitici
Ingegneria del software, 17 maggio 20048
Universitas Mediolanensi
s
Programmi modulariProgrammi modulari
Ingegneria del software, 17 maggio 20049
Universitas Mediolanensi
s
Object-oriented programmingObject-oriented programming
Ingegneria del software, 17 maggio 200411
Universitas Mediolanensi
s
AOP: Cosa sono gli aspettiAOP: Cosa sono gli aspetti
Ingegneria del software, 17 maggio 200413
Universitas Mediolanensi
s
Il problema non è nuovo…Il problema non è nuovo…
• Il flusso di controllo è “tangled”
10 let i = 120 if i > 4 then goto 6030 print i40 i = i + 150 goto 2060 print "done"
Ingegneria del software, 17 maggio 200414
Universitas Mediolanensi
s
Si può risolvere con le buone Si può risolvere con le buone abitudiniabitudini
• Espressione idiomatica (pattern)– Put test at end
10 let i = 120 print i30 i = i + 140 if i < 4 then goto 2050 print "done"
Ingegneria del software, 17 maggio 200415
Universitas Mediolanensi
s
……o fornendo appositi o fornendo appositi strumenti linguisticistrumenti linguistici
int i = 1;while( i < 4 ){ print( i ); i++ }
Ingegneria del software, 17 maggio 200416
Universitas Mediolanensi
s
Aspect Oriented ProgrammingAspect Oriented Programming
• Le problematiche non facilmente incapsulabili vengono dette aspetti [Kiczales97] e programmazione orientata agli aspetti è il filone di ricerca che cerca di identificare i meccanismi linguistici idonei ad isolare il più possibile tali aspetti
Ingegneria del software, 17 maggio 200417
Universitas Mediolanensi
s
L’idea di baseL’idea di base
1. costrutti speciali per isolare gli aspetti (aspects)
2. costrutti per identificare i punti di integrazione (join points)
3. Aspetti vengono poi “intrecciati” da un motore opportuno (weaving)
Ingegneria del software, 17 maggio 200418
Universitas Mediolanensi
s
AspectJ AspectJ [Xerox98][Xerox98]
Java AspectJ
FunctionalComponents
Non-functionalAspects
Weaver
Intertwinedcode
– AspectJ permette di definire join points: punti specifici nel flusso di esecuzione di un programma Java
– Il weaver intreccia) il codice degli aspetti a quello decomposto funzionalmente
Join points
Ingegneria del software, 17 maggio 200419
Universitas Mediolanensi
s
AspectJ exampleAspectJ example
Aspect SimpleTracing {
pointcut traced() :
call (void Display.update () ) ||
call (void Display.repaint (..) );
before() : traced () {
println(“Entering:” + thisJoinPoint);
}
void println (String str) {
<write to appropriate stream> } }
Traced identifies calls to several key methods on Display
Before advice on this pointcut uses a helper method of the aspect to print a message
Advice uses the thisJoinPoint special variable to an object that describes the current join point
Ingegneria del software, 17 maggio 200420
Universitas Mediolanensi
s
Un linguaggio per definire Un linguaggio per definire pointcutpointcut
• call(void Point.setX(int))
• execution(void Point.setX(int))
• handler(ArrayOutOfBoundsException)
• this(SomeType)
• target(SomeType)
• within(MyClass)
• cflow(void Test.main())
• or ("||"), and ("&&"), not ("!").
Ingegneria del software, 17 maggio 200421
Universitas Mediolanensi
s
Parametri e information hidingParametri e information hiding
pointcut setter(): target(Point) && (call(void setX(int)) || call(void setY(int)));
pointcut setter(Point p): target(p) && (call(void setX(int)) || call(void setY(int)));
pointcut testEquality(Point p1, Point p2): target(p1) && args(p2) && call(boolean equals(Object));
Ingegneria del software, 17 maggio 200422
Universitas Mediolanensi
s
Concorrenza e modularitàConcorrenza e modularità
public class Stack implements Constants{
public void push(Object o){ elements[++top] = o; } public Object pop(){ Object ris; ris = elements[top--]; return ris; } private int top = -1; private Object[] elements =
new Object[STACK_SIZE];}
public class Stack implements Constants{ synchronized public void push(Object o){ while (top == STACK_SIZE-1) try{ wait(); } catch (InterruptedException e){ e.printStackTrace(); } elements[++top] = o; if (top == 0) notifyAll(); } synchronized public Object pop(){ Object ris; while (top == -1) try{ wait(); } catch (InterruptedException e){ e.printStackTrace(); } ris = elements[top--]; if (top == STACK_SIZE-2) notifyAll(); return ris; } private int top = -1; private Object[] elements = new Object[STACK_SI ZE];}
L’evoluzione necessaria per
adattare un componente ad
un ambiente concorrente, spesso non è
modulare
Ingegneria del software, 17 maggio 200423
Universitas Mediolanensi
s
L’esempioL’esempio
public class User1 { public void removeUseless(File f){ if(f.isUseless()){ Directory d = f.getDir(); d.removeFile(f); System.out.println("Removed: "
+ f.getName()); }}}
public class User2 { public void updateDir(Directory d){ ...
File f; ...; f.update(); ...}
aspect ConcurrencyAspect{ pointcut file (File f): (instanceof(f) && executions(void
File.update())) || executions(void
User1.removeUseless(f)); pointcut dir (Directory d):
...; static around (File f) returns void: file
(f){ synchronized(f){ proceed(f); }}
static around (Directory d) returns boolean: dir (d){
...}
AspectJ
Java
Quando viene eseguita
f.update() o User1.removeU
seless(f)...
... sincronizza l’esecuzione
sul File f
Attenzione: deadlock prone!
Ingegneria del software, 17 maggio 200424
Universitas Mediolanensi
s
Altri approcciAltri approcci
• Hyper/J [Tarr00]: il software viene considerato un insieme di atomi problemici (concern units) che possono essere aggregati secondo dimensioni arbitrarie.
Ingegneria del software, 17 maggio 200425
Universitas Mediolanensi
s
HyperJHyperJpackage stack : Feature.Kernel // defaultclass stack.Stack : Feature.Kernelclass stack.SynchStack : Feature.Synchoperation stack.Stack.main : Development.Testoperation pop : Feature.Kerneloperation push : Feature.Kernelfield top : Feature.Kernelfield elements : Feature.Kernel
Questi “atomi” vengono poi aggregati in slices: la chiusura transitiva rispetto a ciò che viene usato nel codice
Ingegneria del software, 17 maggio 200426
Universitas Mediolanensi
s
Concerns - Unit of MappingConcerns - Unit of Mapping
• Package Mapping
• Class Mapping
• Interface Mapping
• Operation Mapping
• Field Mapping
• Ogni atomo può essere solo in un modulo normalmente
Ingegneria del software, 17 maggio 200427
Universitas Mediolanensi
s
Member mappingMember mapping
• operation Pkg.Class.method: Feature.concern
• operation foo : Feature.Foo
• Pkg.class.var : Feature.concern
• field fooVar : Feature.Foo
Ingegneria del software, 17 maggio 200428
Universitas Mediolanensi
s
Hyperspace FileHyperspace File
• hyperspace hyperspaceNameclassFileSpecification;classFileSpecification;…
• composable class pkg2.* except pkg2.name;
• composable class pkg3.* including subclasses
• uncomposable class java.lang.*, java.io.*
Ingegneria del software, 17 maggio 200429
Universitas Mediolanensi
s
Hypermodule FileHypermodule File
hypermodule hypermoduleNamehyperslices:
dimensionName1.concernName1,…
relationships:mergeByName |
nonCorrespondingMerge |overrideByNam; …
end hypermodule
Ingegneria del software, 17 maggio 200430
Universitas Mediolanensi
s
Composition StrategyComposition Strategy
• mergeByName (most common)
• nonCorrespondingMerge
• overrideByName (only for methods)
Ingegneria del software, 17 maggio 200431
Universitas Mediolanensi
s
EquateEquate
• equate class dimension1.concern1.class1,
dimension2.concern2.class2;
• equate operation Feature.Kernel.process,
Feature.Check.check_process,
Feature.Eval.eval_process
into myProcess;
Ingegneria del software, 17 maggio 200432
Universitas Mediolanensi
s
OrderOrder
• order action dim2.concern.class.foo
before action dim2.concern2.class2.foo;
• Used for methods. If class is specified then applies to all methods in the class
Ingegneria del software, 17 maggio 200433
Universitas Mediolanensi
s
MergeMerge
• merge class dim1.concern1.class1,
dim2.concern2.class2;
Ingegneria del software, 17 maggio 200434
Universitas Mediolanensi
s
BracketBracket
bracket “*”.”foo”
from action Appl.Concern.Class.barbefore Feature.log.LogClass.invokeBefore($ClassName),
after Feature.log.LogClass.invokeAfter($OperationName)
Ingegneria del software, 17 maggio 200435
Universitas Mediolanensi
s
Cosa hanno in comune i vari Cosa hanno in comune i vari approcciapprocci
• Quantification– Wildcard (lessicali, sintattici, semantici)
• Obliviousness– Il programmatore della parte
decomposta funzionalmente non sa nulla della parte aop