Bonjour,
Depuis peu, je m'interresse à la programmation orientée aspect. j'ai fait un tour du propriétaire du coté d' aspectJ, aspectC++, aspectDNG, aoPHP et PHPaspect.
Dans le but de vraiment rentrer en profondeur dans le sujet, j'ai décidé d'écrire un moteur d'aspect pour php. Pourquoi ?
- aoPHP et PHPaspect ne m'ont pas convaincu ( doc un peu flou et utilisation restrictive pour le premier et implementation legere pour le deuxieme)
- php est procédural et orienté objet
contexte
pour avoir un langage commun, je vais (re)preciser quelques définitions
advice = code à inserer
joinpoint = evenement dans le déroulement du programme (appel de methode, retour de fonction,..)
pointcut = joinpoint satisfaisant une ou plusieurs conditions et où un advice sera inseré ( instanciation de la classe MaClasse au sein de la methode MonAutreClasse::maMethode)
aspect = une unité de définition de pointcut, d'advice
weaver = le generateur chargé d'appliquer un aspect à un code (tissage)
de plus, j'ai rajouté l'enrichissement d'une classe en méthodes et propriétées.
tissage statique et tissage dynamique
statique avant compilation.
dynamique à l'éxécution.
en PHP, il n'existe pas de "compilation" comme en java ou en c, c'est à dire une action du developpeur visant à transformer un langage source en instructions éxécutables.
c'est un peu faux, car le moteur zend compile un bytecode qu'il execute ensuite. j'admet donc que le tissage statique se fera avant la mise en production du code, le dynamique aprés (cas d'aoPHP par exemple, effectuer lors d'une requete) et le "vrai dynamique" par insertion dans le bytecode (quasiment impossible en c ou en c++).
l'implementation
les aspects sont écrits en xml puis transformés en code php. un aspect peut étendre un aspect. le contenu des advices est écrit en php
avantages:
pas de nouveau langage à apprendre,
pas d'interpreteur/compilateur à écrire pour ce langage
inconvénients:
écrire en xml est plus lourd (contraignant ?) que dans un langage (aspectJ proche de java)
les pointcuts sont typés (appel de méthode, ...) et appliqués à un joinpoint si ils valident une expression régulieres.
un tisseur charge un ou plusieurs aspects et les appliquent à un ou plusieurs fichiers.
C'est grosso modo l'approche de PHPaspect mais plus complet.
quelques réflexions
Pratiquement, c'est fortement dépendant du langage cible( peut-on appliquer une condition package comme avec aspectJ en php ?) et du mode de tissage( statique et vrai dynamique)
un joinpoint concretement c'est quoi ? si je m'en tient à ma définition, la déclaration d'une méthode n'en fait pas parti, pourtant si nous voulons appliquer un contrat, nous devons la prendre en compte, particulierement dans un tissage statique.
dans l'expréssion suivante
$object->prop = $another->method();
nous pourrions dire qu'il existe deux joinpoint éxécuté dans l'ordre
$another->method() <-- appel d'une méthode
$object->prop <-- affectation d'une valeur à une propriétée.
en tissage statique et dynamique, tisser entre les deux implique une modification du code qui peut rapidement devenir ingérable.
1 2 3
| $tmp = $another->method();
//advice
$object->prop = $tmp; |
en tissage "vrai dynamique", c'est faisable ( voir le package intercept dans PECL) en insérant du byte code, mais obliqe à maitriser completement le fonctionement du moteur (quelles implications pour une insertion de bytecode ?).
pour faire augmenter la température, considerez ceci
1 2 3
|
if($another->method())
something(); |
les structures de langage (if, switch) sont-elles des joinpoint ?
les instructions spécifiques à un langage (exit, die, echo) sont-elles des joinpoint ?
elles sont des événements notables dans l'exécution du programme!
Outil ou nouvelle architecture?
pour des applications de log ou de mise au point, c'est un outil efficace mais penser aspect implique fatalement une évolution de la modélisation objet (et quelque part des langages -> aspectJ).
à suivre ...
Voila à chaud et un peu en vrac, n'hésitez pas à faire part de vos remarques
++
Partager