web-dev-qa-db-fra.com

Programmation orientée aspect vs programmation orientée objet

Comme la plupart des développeurs ici et dans le monde entier, je développe depuis plusieurs années des systèmes logiciels utilisant les techniques de programmation orientée objet (OOP). Donc, quand je lis que la programmation orientée aspect (AOP) aborde beaucoup des problèmes que la OOP) traditionnelle ne résout pas complètement ou directement, je fais une pause et je pense, est-ce réel?

J'ai lu beaucoup d'informations en essayant d'apprendre les clés de ce paradigme AOP et je suis au même endroit. Je voulais donc mieux comprendre ses avantages pour le développement d'applications dans le monde réel.

Est-ce que quelqu'un a la réponse?

186
yeradis

Pourquoi "vs"? Ce n'est pas "vs". Vous pouvez utiliser la programmation orientée aspect en combinaison avec la programmation fonctionnelle, mais également en combinaison avec la programmation orientée objet. Ce n'est pas "vs", c'est "Programmation Orientée Aspect avec Programmation Orientée Objet".

Pour moi, AOP est une sorte de "méta-programmation". Tout ce que fait AOP pourrait aussi être fait sans cela en ajoutant simplement du code. AOP vous enregistre simplement en écrivant ce code.

Wikipedia a l'un des meilleurs exemples pour cette méta-programmation. Supposons que vous avez une classe graphique avec de nombreuses méthodes "set ... ()". Après chaque méthode de réglage, les données graphiques ont changé, donc les graphiques ont changé et les graphiques doivent donc être mis à jour à l'écran. Supposons de repeindre les graphiques que vous devez appeler "Display.update ()". L'approche classique consiste à résoudre ce problème en ajoutant plus de code. A la fin de chaque méthode définie, vous écrivez

void set...(...) {
    :
    :
    Display.update();
}

Si vous avez 3 méthodes set, ce n'est pas un problème. Si vous en avez 200 (hypothétique), il devient vraiment pénible d’ajouter cela partout. De plus, chaque fois que vous ajoutez une nouvelle méthode set, vous devez être sûr de ne pas oublier de l'ajouter à la fin, sinon vous venez de créer un bogue.

AOP résout ce problème sans ajouter des tonnes de code, mais vous ajoutez un aspect:

after() : set() {
   Display.update();
}

Et c'est tout! Au lieu d'écrire le code de mise à jour vous-même, vous indiquez simplement au système qu'après l'atteinte d'un setcut (), il doit exécuter ce code et exécutera ce code. Pas besoin de mettre à jour 200 méthodes, pas besoin de s'assurer de ne pas oublier d'ajouter ce code sur une nouvelle méthode set. De plus, vous avez juste besoin d'un point de coupe:

pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);

Qu'est-ce que ça veut dire? Cela signifie que si une méthode est nommée "set *" (* signifie que tout nom peut suivre après set), quel que soit le résultat renvoyé par la méthode (premier astérisque) ou les paramètres utilisés (troisième astérisque) et = il s’agit d’une méthode de MyGraphicsClass et cette classe fait partie du package "com.company. *", il s’agit donc d’un pointcut set (). Et notre premier code dit " après, si vous exécutez une méthode qui est un setcut, exécutez le code suivant".

Voyez comment AOP résout élégamment le problème ici? En réalité, tout ce qui est décrit ici peut être fait au moment de la compilation. Un préprocesseur AOP peut simplement modifier votre source (par exemple, en ajoutant Display.update () à la fin de chaque méthode set-pointcut) avant même de compiler la classe elle-même.

Cependant, cet exemple montre également l’un des gros inconvénients de l’AOP. AOP est en train de faire quelque chose que beaucoup de programmeurs considèrent comme un "Anti-Pattern". Le motif exact s'appelle " Action à distance ".

Une action à distance est un anti-modèle (une erreur commune reconnue) dans lequel le comportement d'une partie du programme varie énormément en fonction de la difficulté ou de l'impossibilité d'identifier les opérations d'une autre partie du programme.

En tant que débutant dans un projet, je pourrais simplement lire le code de toute méthode set et le considérer comme cassé, car il ne semble pas mettre à jour l'affichage. Je ne vois pas en regardant simplement le code d'une méthode-set, qu'après l'avoir exécutée, un autre code sera exécuté "par magie" pour mettre à jour l'affichage. Je considère cela comme un sérieux inconvénient! En apportant des modifications à une méthode, des bugs étranges peuvent être introduits. Comprendre plus en détail le flux de code dans lequel certaines choses semblent fonctionner correctement, mais ne sont pas évidentes (comme je l’ai dit, elles fonctionnent comme par magie ... d’une manière ou d’une autre), est vraiment difficile.

Mise à jour

Juste pour clarifier ceci: Certaines personnes pourraient avoir l’impression que je dis que la PAD est quelque chose de mauvais et qu’elle ne devrait pas être utilisée. Ce n'est pas ce que je dis! AOP est en fait une fonctionnalité intéressante. Je viens de dire "Utilisez-le avec précaution". AOP ne causera des problèmes que si vous mélangez le code normal et AOP pour le même Aspect. Dans l'exemple ci-dessus, nous avons l'aspect de la mise à jour des valeurs d'un objet graphique et du dessin de l'objet mis à jour. C'est en fait un seul aspect. Coder la moitié en code normal et l’autre moitié en aspect est ce qui ajoute au problème.

Si vous utilisez AOP pour un aspect complètement différent, par exemple, pour vous connecter, vous ne rencontrerez pas le problème anti-pattern. Dans ce cas, un débutant dans le projet pourrait se demander "D'où viennent tous ces messages de journal? Je ne vois aucune sortie de journal dans le code", mais ce n'est pas un énorme problème. Les modifications qu'il apporte à la logique du programme ne vont pas interrompre la fonction de journalisation et les modifications apportées à celle-ci ne vont pas rompre la logique de son programme - ces aspects sont totalement séparés. L'utilisation d'AOP pour la journalisation présente l'avantage que votre code de programme peut se concentrer entièrement sur ce qu'il devrait faire et que vous pouvez toujours disposer d'une journalisation sophistiquée, sans que votre code ne soit encombré par des centaines de messages de journalisation partout. De plus, lorsqu'un nouveau code est introduit, les messages de journalisation apparaissent comme par magie au bon moment avec le bon contenu. Le programmeur débutant peut ne pas comprendre pourquoi ils sont là ou d’où ils viennent, mais comme ils enregistreront la "bonne chose" au "bon moment", il peut accepter avec plaisir le fait qu’ils soient là et passer à autre chose. .

Donc, une bonne utilisation de AOP dans mon exemple serait de toujours se connecter si une valeur a été mise à jour via une méthode set. Cela ne créera pas d'anti-pattern et ne sera pratiquement jamais la cause d'un problème.

On pourrait dire que si vous pouvez facilement abuser de l'AOP pour créer autant de problèmes, c'est une mauvaise idée de tout utiliser. Cependant, quelle technologie ne peut pas être utilisée de manière abusive? Vous pouvez abuser de l'encapsulation de données, vous pouvez abuser de l'héritage. Pratiquement toutes les technologies de programmation utiles peuvent être utilisées à mauvais escient. Considérez un langage de programmation si limité qu'il ne contient que des fonctionnalités qui ne peuvent pas être utilisées de manière abusive. une langue dans laquelle les fonctionnalités ne peuvent être utilisées que dans la mesure où elles étaient initialement prévues. Un tel langage serait tellement limité qu'il serait discutable de l'utiliser s'il pouvait même être utilisé pour une programmation dans le monde réel.

302
Mecki

OOP et AOP ne s'excluent pas mutuellement. AOP peut être un bon ajout à la POO. AOP est particulièrement pratique pour ajouter du code standard tel que la journalisation, le suivi des performances, etc. aux méthodes sans encrasser le code de la méthode avec ce code standard.

27
norbertB

la pogrammation orientée vers l’aspect fournit un moyen pratique d’implémenter des problèmes transversaux tels que la journalisation, la sécurité. Ces aspects transversaux sont des éléments de la logique qui doivent être appliqués à de nombreux endroits mais qui n’ont en réalité rien à voir avec la logique métier.

Vous ne devriez pas considérer AOP comme un substitut de OOP, mais plutôt comme un complément de Nice, qui rend votre code plus propre, à couplage faible et centré sur la logique métier. Donc, en appliquant l'AOP, vous obtiendrez 2 avantages majeurs:

  1. La logique de chaque problème est maintenant au même endroit, au lieu d'être dispersée dans la base de code.

  2. les classes sont plus propres puisqu'elles ne contiennent du code que pour leur préoccupation principale (ou fonctionnalité principale) et que les préoccupations secondaires ont été déplacées vers des aspects.

27
nkr1pt

Je pense qu’il n’ya pas de réponse générale à cette question mais une chose à noter est que AOP ne remplace pas OOP = mais ajoute certaines caractéristiques de décomposition qui traitent la soi-disant tyrannie de la composition dominante ( 1 ) (ou préoccupations transversales) .

Cela aide sûrement dans certains cas tant que vous maîtrisez les outils et les langages à utiliser pour un projet spécifique, mais ajoute également un nouveau niveau de complexité en ce qui concerne l'interaction des aspects et le besoin d'outils supplémentaires comme le AJDT pour toujours comprendre votre programme.

Gregor Kiczales a déjà donné une conférence d’introduction intéressante sur l’AOP lors de Google Tech Talks que je recommande de regarder: Programmation orientée aspect: recherche radicale dans la modularité .

10
fhe

Tout d'abord, AOP ne remplacera pas OOP. AOP étend la POO. Les idées et pratiques de OOP restent pertinentes. Avoir une bonne conception d'objet facilitera probablement son extension avec des aspects.

Je pense que les idées apportées par AOP sont importantes. Nous devons trouver des moyens de mettre en œuvre des préoccupations transversales pour différentes classes de votre programme sans avoir à changer les classes elles-mêmes. Mais je pense que l'AOP finira par faire simplement partie d'autres outils que nous utilisons et non d'un outil ou d'une technique distinct. Nous voyons déjà cela se produire.

Quelques langages dynamiques tels que Ruby et Python ont des constructions de langage telles que mixins qui résolvent les mêmes problèmes. Cela ressemble beaucoup à AOP mais est mieux intégré dans la la langue.

Spring and Castle et quelques autres infrastructures d'injection de dépendance ont des options pour ajouter un comportement aux classes qu'ils injectent. C’est une façon de tisser à la volée et je pense que cela a beaucoup de potentiel.

Je ne pense pas que vous deviez apprendre un tout nouveau paradigme pour utiliser AOP. Les idées sont intéressantes mais sont lentement absorbées par les outils et les langages existants. Restez informé et testez ces outils.

8
Mendelt

Je suis en retard pour répondre à cette question, mais c’est l’un de mes sujets préférés, alors laissez-moi vous faire part de mon point de vue.

OOP est principalement utilisé pour organiser votre logique métier while AOP aide à organiser votre choses non-fonctionnelles comme l'audit, la journalisation, la gestion des transactions, la sécurité, etc.

De cette façon, vous pouvez découpler votre logique métier avec une logique non fictive qui rend le code plus propre.

L'avantage Otter est que vous pouvez appliquer les conseils (exemple d'audit) de manière très cohérente sans implémenter d'interface, ce qui offre une grande flexibilité pour la modification sans toucher à la logique métier.

1
Gaurang Popat

AOP est un nouveau paradigme de programmation traitant de ce concept. Un aspect est une entité logicielle implémentant une partie non fonctionnelle spécifique de l'application.

Je pense que cet article est un bon point de départ pour la programmation orientée aspect: http://www.jaftalks.com/wp/index.php/introduction-to-asaspect-oriented-programming/

1
JafTalks