AOP vs fonctionnalités

La programmation orientée aspect (AOP) est un paradigme de programmation assez populaire. L' article de Wikipédia explique bien la motivation de cette approche.

image

L'AOP est un excellent outil pour les concepts globaux, tels que: la journalisation, qui, directement, n'affecte pas la logique du code.

Cependant, des problèmes avec AOP sont découverts lorsqu'il est utilisé pour des besoins commerciaux tels que l'autorisation. Ces aspects doivent être clairement visibles dans le code approprié afin que le développeur puisse voir immédiatement lors de la lecture du code source s'ils sont correctement mis en œuvre. Les frameworks AOP résolvent généralement ce problème avec des annotations:

@RequireRole(Role.Admin) // clearly visible aspect fun updateUserPermissions(…) { // logic here } 

Cependant, en termes de lisibilité, elle n'est pas très différente de l'approche fonctionnelle, en utilisant la méthode requireRole au lieu d'annotation.

Note du traducteur : dans l'article d'origine, l'expression utilisée lors de la réécriture d'une manière fonctionnelle ou d' une approche fonctionnelle peut être interprétée comme utilisant une approche fonctionnelle ou un appel de fonction direct / spécifique. L'article contient des exemples qui peuvent être interprétés de différentes manières.

Aussi:

1. À l'avenir, nous reviendrons sur le concept de fonctions d'ordre supérieur

2. L'article rencontre le mot aspect, qui est l'anglais et le concept sous l' aspect AOP


 fun updateUserPermissions(…) { requireRole(Role.Admin) // throws SecurityException // logic here } 

De plus, l'approche fonctionnelle a l'avantage de s'adapter à des contrôles de contrôle d'accès plus complexes, tels que l'analyse des paramètres de méthode, avant de décider quel rôle d'utilisateur est requis.

Il en va de même pour d'autres types d'aspects, tels que les transactions. Malheureusement, la présentation fonctionnelle de concepts plus complexes en Java est lourde et peu pratique, ce qui crée la popularité artificielle des cadres AOP dans l'écosystème Java.

Dans Kotlin, au lieu d'une approche de transaction de type Java utilisant AOP et des annotations comme ceci:

 @Transactional fun updateUserPermissions(…) { // logic here } 

Il est également lisible et semble propre lorsqu'il est réécrit sans annotations, avec une approche fonctionnelle.

 fun updateUserPermissions(…) = transactional { // logic here } 

L'avantage de cette approche est que vous pouvez toujours appuyer sur Ctrl / Cmd + cliquer sur la déclaration de fonction transactionnelle dans votre IDE et voir immédiatement ce qu'elle fait exactement. Ce qui n'est généralement pas possible avec aucun des cadres AOP couramment utilisés. Même lorsque la navigation vers le code d'aspect est fournie à l'aide du plug-in IDE, le décryptage de sa logique nécessite la connaissance d'une API multifonctionnelle et / ou de conventions distinctes.

Malheureusement, il y a des problèmes avec la mise à l'échelle de la façon de remplacer les annotations AOP dans Kotlin. Pour le cas où plusieurs aspects sont appliqués à la même fonction, avec accumulation d'accolades et de tirets:

 fun updateUserPermissions(…) = logged { transactional { // logic here } } 

Une solution de contournement consiste à créer une fonction d'ordre supérieur pour conserver le code acceptable lors de l'application de plusieurs aspects:

 fun updateUserPermissions(…) = loggedTransactional { // logic here } 

Un autre inconvénient de l'approche fonctionnelle est que des aspects tels que la journalisation nécessitent l'accès aux paramètres de la méthode. Ils sont généralement disponibles dans les frameworks AOP via des API spéciales, mais en utilisant les fonctions du langage Kotlin standard, vous ne pouvez pas y accéder facilement. Ainsi, afin de présenter réellement un exemple réel de l'aspect de la journalisation, sous une forme purement fonctionnelle, vous devez encore écrire une quantité importante de code de plaque de chaudière :

 fun updateUserPermissions(params: Params) = logged("updateUserPermissions($params)") { // logic here } 

Cette considération fait toujours d'AOP l'outil de journalisation préféré lorsque vous avez vraiment besoin de l'avoir globalement et de manière cohérente dans votre application. Dans le même temps, l'utilisation d'AOP pour des fonctionnalités telles que l'autorisation et les transactions est un abus, compte tenu des riches abstractions fonctionnelles disponibles dans Kotlin. Les fonctions répondent mieux à ces exigences et sont plus propres.

En conclusion, je dirais qu'une amélioration supplémentaire des abstractions fonctionnelles pour fournir un remplacement encore meilleur de l'AOP pourrait être un vecteur prometteur pour le développement futur du langage Kotlin. Les frameworks AOP basés sur Java sont généralement spécifiques à la JVM et perçus comme magiques, tandis que les abstractions fonctionnelles de Kotlin sont vraiment multi-plateformes et transparentes pour l'utilisateur.
Note du traducteur :
1. Article sur le support (eng) .
2. L'auteur de l'article original est Roman Elizarov (chef d'équipe JetBrains, travaillant sur les coroutines et bibliothèques Kotlin, la programmation sportive / ICPC, la concurrence et les algorithmes, les mathématiques / la finance quantitative; anciennement Devexperts). Sur Habr elizarov

Source: https://habr.com/ru/post/fr435454/


All Articles