Certains problèmes sont-ils résolus plus élégamment avec AOP?


19

Je suis tombé sur l'idée de la programmation orientée vers les aspects, et cela m'inquiète.

L'idée de base semble être que nous voulons prendre des préoccupations transversales qui ne sont pas bien modulaires en utilisant l'objet et les modulariser. Tout cela est très bien et bien.

Mais l'implémentation d'AOP semble être celle de la modification du code depuis l'extérieur du module. Ainsi, par exemple, un aspect pourrait être écrit qui change ce qui se passe lorsqu'un objet particulier est passé en tant que paramètre dans une fonction. Cela semble aller directement à l'encontre de l'idée des modules. Je ne devrais pas être en mesure de modifier le comportement d'un module de l'extérieur de ce module, sinon le point entier des modules est renversé. Mais les aspects semblent faire exactement cela!

Fondamentalement, les aspects semblent être une forme de correction de code. Cela peut être utile pour certains hacks rapides; mais, comme principe général, ce n'est peut-être pas quelque chose que vous voulez faire. La programmation orientée aspect me semble prendre une mauvaise pratique et passer à un principe général de conception.

L'AOP est-il une bonne pratique? Certains problèmes de programmation sont-ils résolus plus élégamment avec AOP?


ahhh, le fameux patch singe!
Muad'Dib

1
J'ai modifié la question pour en améliorer le ton et j'ai voté pour la réouvrir.
Robert Harvey

Questio a également été redemandé sous une forme différente ici: programmers.stackexchange.com/questions/19344/…
Peter Boughton

Réponses:


19

La programmation orientée vers l'aspect permet de faire certains types de programmation difficiles à faire sans disperser inutilement du code dans votre application ou bibliothèque qui n'est pas lié aux fonctions principales de votre logiciel (c.-à-d. Préoccupations transversales). Les exemples comprennent:

  1. Journalisation et surveillance
  2. Analyse de performance
  3. Débogage et suivi
  4. Annuler la fonctionnalité
  5. Validation des entrées et sorties
  6. Morphing du comportement des objets existants
  7. Filtres d'objets
  8. Implémentation de la sécurité
  9. Gérer les transactions

En limitant ces préoccupations transversales à une seule partie de l'application, puis en référençant ces fonctionnalités dans le code via des attributs, l'interception d'appels de méthode ou des proxys dynamiques, vous autorisez l'encapsulation du comportement transversal; cela présente tous les avantages (c'est-à-dire un seul point de modification) que l'encapsulation fournirait n'importe où ailleurs dans votre application.

Le point clé ici est que l'AOP encapsule un comportement qui est 1) commun à l'ensemble de l'application et 2) périphérique à la fonctionnalité principale de l'application.


7

J'arrive tard dans le jeu, mais je fournis cela aux développeurs ultérieurs qui pourraient tomber sur cette question.

Je déconseille fortement AOP si votre application en dépend pour fonctionner correctement. Les aspects fonctionnent comme ceci:

  • Des conseils (comportement supplémentaire) sont appliqués à
  • Points de jonction (endroits où le code supplémentaire peut être attaché, une telle méthode commence ou se termine, ou lorsqu'un événement donné se déclenche)
  • ... où pointcut (un motif qui détecte si un point de jointure donné correspond) les motifs correspondent

Pour quiconque fait des ordinateurs depuis longtemps, le fait que des modèles soient utilisés pourrait être quelque chose à regarder de près. Voici donc un exemple de pointcut qui correspond à n'importe quelle méthode nommée setquels que soient les arguments:

call(* set(..))

C'est donc un point de vue assez large et il devrait être clair que la manipulation avec soin est conseillée (sans jeu de mots) parce que vous appliquez des conseils à beaucoup de choses.

Ou diable, appliquons des conseils à tout , quel que soit le nom ou la signature!

execution(* *(..))

Donc, clairement, nous devons être prudents car il y a beaucoup de puissance ici, mais ce n'est pas un argument contre les aspects - c'est un argument pour la prudence car il y a beaucoup de puissance ici et la correspondance de modèles peut facilement aller de travers (il suffit de frapper votre moteur de recherche préféré pour aop bugs et amusez-vous).

Voici donc à quoi ressemble un pointcut relativement sûr:

pointcut setter(): target(Point) &&
                   ( call(void setX(int)) ||
                     call(void setY(int)) );

Cela fournit explicitement des conseils si des méthodes nommées setXou setYsur un Pointobjet sont trouvées. Les méthodes ne peuvent recevoir que des ints et elles doivent l'être void. Semble assez sûr, non? Eh bien, c'est sûr si ces méthodes existent et que vous avez appliqué les bons conseils. Sinon, tant pis; il échoue silencieusement.

Pour donner un exemple, un ami essayait de déboguer une application Java où tout le monde de temps en temps, cela retournerait des données incorrectes. C'était un échec peu fréquent et ne semblait pas être en corrélation avec un événement particulier ou des données en particulier. C'était un bug de threading, quelque chose qui est notoirement difficile à tester ou à détecter. Il s'est avéré qu'ils utilisaient des aspects pour verrouiller les méthodes et les rendre "thread-safe", mais un programmeur a renommé une méthode et un pointcut n'a pas réussi à la faire correspondre, provoquant ainsi une interruption silencieuse de l'application.

Ainsi, je dis aux gens que s'ils doivent utiliser AOP, pour traiter des aspects comme les exceptions: dans un système bien conçu et si rien ne va mal, ils peuvent être supprimés et le logiciel fonctionne toujours correctement. Cependant, si la fonctionnalité du programme dépend d'AOP, vous introduisez une fragilité injustifiée dans votre programme.

Ainsi, la journalisation, le débogage et le traçage sont d'excellents exemples de comportements qui sont parfaits pour les aspects, mais la sécurité? Nan. Sécurité des fils? Nan.

Pour une alternative robuste à l'AOP, voir traits . Plutôt que d'être boulonnés sur le langage, ils y sont directement intégrés, n'ont pas besoin d'un IDE "sensible aux traits" (bien que cela puisse aider) et ont des échecs de compilation si les méthodes dont vous avez besoin ne sont pas présentes. Les traits font un travail beaucoup plus propre de gérer la séparation des préoccupations parce que le problème a été mieux défini dès le départ. Je les utilise beaucoup et ils sont fantastiques.


Plutôt que d'affirmer que l'AOP ne devrait pas être utilisé pour les fonctionnalités de base, il peut être plus approprié de dire que les coupes de points qui s'appuient sur les noms de méthode sont une mauvaise idée. Je dirais probablement que le verrouillage et la synchronisation ne sont pas non plus de bons cas d'utilisation pour AOP.
Code Bling

2

Une situation dans laquelle AOP pourrait être la seule solution décente et pratique est lorsque vous n'avez pas accès au code source . Pour utiliser le vieil exemple fatigué du problème transversal de l'exploitation forestière:

Supposons que vous souhaitiez enregistrer le flux de contrôle dans une bibliothèque tierce que vous consommez. Vous avez votre propre code entièrement instrumenté avec des instructions de journalisation. Cependant, pour cette bibliothèque, vous n'avez pas la source, ce qui rend impossible l'ajout de vos instructions de journalisation. Puisque vous n'avez le bytecode, AOP vous permet d'instrumenter cette bibliothèque tiers de toute façon.

Et si vous créez de toute façon un aspect de journalisation, vous pourriez également envisager d'implémenter la journalisation avec AOP dans votre propre code.


La journalisation est pour des choses "intéressantes". Comment pouvez-vous faire autre chose que «entrer avec ces paramètres» et «quitter» avec la journalisation AOP?

@Thorbjorn: la journalisation / le débogage / le traçage n'est qu'un des nombreux domaines de fonctionnalité avec lesquels AOP peut vous aider. Je l'ai utilisé comme exemple pour illustrer mon propos. Le point que j'essaye de faire est que AOP vous donne plus de contrôle sur le bytecode tiers.
Joseph Tanenbaum

bien sûr, mais je voulais vraiment savoir si la journalisation AOP pouvait faire plus que la journalisation entrée-sortie?

Cela dépend de l'outil AOP que vous utilisez, mais il y a certainement des limites à ce que vous pouvez faire. Il pourrait très bien être impossible d'aller au-delà de la journalisation entrée-sortie.
Joseph Tanenbaum
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.