Nell'ultimo decennio si è vista una rapida diffusione dell'Object Oriented Programming (OOP) come metodologia predominante nello sviluppo software, ponendosi come successore della programmazione procedurale. Grazie all'utilizzo di classi e interfacce e a concetti come ereditarietà, polimorfirsmo e incapsulamento è possibile scrivere del software modulare, facilmente manutenibile e riutilizzabile.
Ciò nonostante esistono alcuni comportamenti che per la loro natura di trasversalità applicativa non sono facilmente isolabili in moduli distinti, pensiamo ad esempio al logging o alla gestione della sicurezza. La gestione di questi aspetti, pur non rappresentando il core business applicativo, è presente in più oggetti del modello, ed anche se è possibile gestire tali problematiche con un sapiente utilizzo dei design pattern, determina comunque un elemento di disturbo architetturale.
Per far fronte a queste problematiche nasce l'Aspect Oriented Programming (AOP), un paradigma complementare a OOP in grado di descrivere aspetti e comportamenti trasversali all'applicazione, separandoli dal dominio applicativo.
Concetti fondamentali dell'AOP
La comprensione di AOP passa attraverso alcuni concetti fondamentali:
Crosscutting Concern
Comportamento trasversale all'applicazione che si ripercuote in più punti dell'object model. Ne sono un esempio il caching, il logging, l'autenticazione o il Transaction Management. AOP nasce per cercare di isolare i crosscutting concern in moduli ben precisi.
Aspect
È l'equivalente di una classe in OOP ed è utilizzata nella programmazione ad aspetti per modularizzare i crosscutting concern. Grazie agli aspect è possibile aggiungere dinamicamente comportamenti agli oggetti di dominio senza che questi ne siano a conoscenza.
Un aspect comprende:
- un insieme di Advice che ne implementano le logiche applicative
- i Pointcut che ne regolano l'esecuzione
Join Point
Rappresenta un punto preciso nell'esecuzione del programma, come l'invocazione di un metodo o il verificarsi di un eccezione.
Advice
Descrive l'operazione da compiere da parte di un aspetto ad un determinato Join Point. Un advice, a differenza di un metodo che deve essere invocato esplicitamente, viene eseguito automaticamente ogni volta che ad un determinato evento (Join Point) si verifica una particolare condizione (Pointcut). Esistono diversi tipi di Advice:
Tipo di Advice | Momento dell'esecuzione |
---|---|
BeforeAdvice |
prima dell'esecuzione di un Join Point |
AfterReturning |
dopo l'esecuzione di un Join Point in assenza di eccezioni |
AfterThrowing |
dopo l'esecuzione di un Join Point che ha generato un eccezione |
AfterAdvice |
dopo l'esecuzione di un Join Point indipendentemente dal suo esito |
AroundAdvice |
costituisce l'Advice più versatile in quanto consente di prendere il controllo dell'intero Join Point. Non solo è possibile specificare le stesse cose degli Advice precedenti ma è anche possibile decidere quando e se eseguire il Join Point o addirittura generare eccezioni |
Pointcut
Descrive le regole con cui associare l'esecuzione di un Advice ad un determinato Join Point. Sostanzialmente attraverso un predicato viene specificato che al verificarsi di un determinato Join Point (es: esecuzione del metodo foo()
) sia applicato un determinato Advice (es: Before).
Target
Anche chiamato Advised Object rappresenta l'oggetto sul quale agisce l'Advice.