|
|
Aspect Oriented Programming - syntax
|
L'implementazione dell'AOP che ho realizzato è semplice, ma sufficiente per un primo approccio all'AOP.
Gli elementi base che ho implementato sono essenzialmente tre:
- aspect
- pointcut
- advice and introduction
Un aspect è definito con la seguente sintassi:
aspect nameOfTheAspect {
....
#aspect definition: pointcuts, advices, introductions..
....
}
I pointcut non sono altro che delle dichiarazioni usate per individuare punti ben precisi del codice, punti
usati successivamente dagli advices o dalle introduction per modificare il comportamento
dell'applicativo (ad esempio aggiungendo/sostituendo del codice).
Genericamente ad ogni pointcut dovrà essere attribuito un nome, seguito dalla specificazione del tipo di pointcut e
dalla specificazione del pattern per l'individuazione del punto esatto dove applicare le modifiche al codice.
pointcut pt_name -class classname_spec
pointcut pt_name -call methodname_spec
pointcut pt_name -trace membername_spec
dove classname_spec, methodname_spec e membername_spec sono delle liste di
nomi che permettono l'individuazione di un gruppo di classi/metodi/membri sulla base del nome loro assegnato.
Il tipo di pointcut -trace l'ho previsto ma, sfortunatamente è ancora da implementare.
Un esempio di classname_spec potrebbe essere ad esempio:
pointcut AllFile -class {File* *File}
#we can use the wildcard characters '*' and '?'
Questo pointcut intercetta tutte le classi del nostro progetto il cui nome inizia per File oppure termina per
File. Quindi verranno intercettate le classi con nomi tipo: MyFile, RegisterFile, DocFile, FileList ecc.
(attenzione che il TCL è comunque, sempre 'case sensitive', quindi occhio alle maiuscole e minuscole!)
Su un pointcut di tipo -class possiamo quindi implementare delle introduction.
Un' introduction semplicemente permette di specificare le modifiche da apportare alle classi intercettate
da uno o più pointcut.
introduction name -parent pointcutNameList newParents
introduction name -interface pointcutNameList newInterfaces
introduction name -code pointcutNameList newCode
dove i tipi -parent, -interface e -code permettono di:
- -parent: aggiungere classi da cui derivano le classi intercettate
- -interface: aggiungere delle interfacce alle classi intercettate
- -code: aggiungere del codice (tipicamente nuovi metodi) alle classi intercettate.
Per esempio, utilizzando il pointcut AllFile dichiarato nell'esempio precedente, posso scrivere:
introduction addGetFileLength -code {AllFile} {
proc getFileLength {filename} {
return [file $filename size ]
}
}
Con questa introduction ogni classe il cui nome inizia e/o termina con la parola 'File', avrà aggiunto una
procedura che mi restituira' la lunghezza di un file.
Seguendo lo stesso principio è possibile scrivere un pointcut di tipo -call
pointcut AllOpenFileMethods -call {File* open* *File open*}
#we can use the wildcard characters '*' and '?'
In questo caso il pointcut AllOpenFileMethods intercetterà, in tutte le classi il cui nome inizia o termina per 'File',
i metodi (sia virtuali che non) il cui nome inizia per 'open'.
Sarà quindi possibile usando questo pointcut scrivere un advice per modificare il codice dei metodi intercettati come per esempio:
advice -after { AllOpenFileMethods } {
puts "the file is opened"
}
Il termine -after si riferisce all'istruzione precedente a un qualsiasi punto di ritorno da un metodo di una classe.
Quindi o semplicemente l'ultima riga di codice del metodo o appena prima di una qualsiasi istruzione return
Il termine -before farà invece riferimento alla prima riga di codice dei metodi intercettati, ovvero il codice definito
nel nostro 'advice' verrà eseguito prima di ogni altra cosa all'interno di questi metodi.
il termine -around infine, servirà per sostituire completamente il codice dei metodi intercettati con quello scritto nel
corpo del nostro 'advice'
Riporto infine la nota completa (contenuta nel codice del tclaop script) riguardante la sintassi.
Da notare alcune cose che ho già previsto di aggiungere, ma purtroppo non ho ancora avuto il tempo di
implementare .
# this simple implementation of AOP consist in a namespace Aspect and a global
# procedure "aspect".
# Within it you can declare some "pointcut" and "advice"
#
# 1) All the aspect(s) declaration(s) must be at the start of the source code,
# before any class declaration
# 2) pointcut must be defined as a couple of names of type
# "<class> <proc/method>" Note that <class> and <proc/method>
# name can contains glob char "*?" to match more than one name
# 3) advice will be declared after all the pointcuts declaration
# in the advice body, if the string "functionName" is presents, then a
# variable functionName containing the name of the current function will be set
# example:
# aspect nameOfAspect {
# pointcut AA -call <classname procname>
# pointcut AA -call <classname2 procname2 classname3 procname3 ... >
# pointcut BB -call <&...same as above...>
# advice -after AA ?BB? {
# <lines of code to be executed>
# ....
# }
# advice -before AA ?? {
# <lines of code...>
# }
# }
# Syntax:
# pointcut <pt_name> -class <classname_spec>
# introduction <name> -parent <pointcutNameList> <newParents>
# introduction <name> -interface <pointcutNameList> <newInterfaces>
# introduction <name> -code <pointcutNameList> <newCode>
# introduction <name> -name <pointcutNameList> <newClassName>
# (create a new class definition that can be used in following advice )
#
# pointcut <pt_name> -call <methodname_spec>
# advice <name> -around <pointcutNameList> <code>
# advice <name> -before <pointcutNameList> <code>
# advice <name> -after <pointcutNameList> <code>
# advice <name> -cflow <pointcutNameList> <code> --- Not Yet Implemented
#
# pointcut <pt-name> -trace <membername_spec> --- Not Yet Implemented
# evaluate <name> -set <pointcutNameList.> --- Not Yet Implemented
# evaluate <name> -get <pointcutNameList> --- Not Yet Implemented
# evaluate <name> -both <pointcutNameList> --- Not Yet Implemented
|
Copyright © 2002, by eriskouma.com. All rights reserved. last modified on: Sat, 09 November 2002
|
|