Je ne sais pas pourquoi, mais j'ai toujours l'impression de "tricher" lorsque j'utilise la réflexion - c'est peut-être à cause de la performance que j'ai subie, je sais que je prends.
Une partie de moi dit, si cela fait partie du langage que vous utilisez et que cela peut accomplir ce que vous essayez de faire, alors pourquoi ne pas l'utiliser. L'autre partie de moi dit qu'il doit y avoir un moyen de faire cela sans utiliser de réflexion. Je suppose que cela dépend peut-être de la situation.
Quels sont les problèmes potentiels que je dois surveiller lorsque j'utilise la réflexion et quel est mon intérêt? Combien d'effort vaut la peine de dépenser pour essayer de trouver une solution plus conventionnelle?
Réponses:
Non, ce n'est pas de la triche, c'est un moyen de résoudre des problèmes dans certains langages de programmation.
Aujourd'hui, ce n'est souvent pas la meilleure solution (la plus propre, la plus simple, la plus facile à gérer). S'il existe un meilleur moyen, utilisez-le bien. Cependant, parfois il n'y en a pas. Ou, s’il y en a un, c’est beaucoup plus complexe, il faut beaucoup de duplication de code, etc., ce qui le rend infaisable (difficile à maintenir à long terme).
Deux exemples de notre projet actuel (Java):
fieldX
au champ approprié de la classe et pour initialiser ce dernier. Dans certains cas, il peut créer une boîte de dialogue simple à partir des propriétés identifiées à la volée. Sans réflexion, cela prendrait des centaines de lignes de code dans plusieurs applications. La réflexion nous a donc permis de mettre au point un outil simple, rapide et sans problème, et de nous concentrer sur l’essentiel (tests de régression de notre application Web, analyse des journaux de serveur, etc.) plutôt que sur des questions non pertinentes.Comme tout outil puissant, la réflexion peut également être utilisée pour se tirer une balle dans le pied. Si vous apprenez quand et comment (ne pas) l'utiliser, cela peut vous apporter des solutions élégantes et propres à des problèmes autrement difficiles. Si vous en abusez, vous pouvez transformer un problème simple en un désordre complexe et laid.
la source
if (propName = n) setN(propValue);
, vous pouvez nommer vos balises XML de la même manière que vos propriétés de code et les exécuter en boucle. Cette méthode simplifie également l'ajout de propriétés ultérieurement.Ce n'est pas tricher. Mais c'est généralement une mauvaise idée dans le code de production pour au moins les raisons suivantes:
Je suggérerais de limiter l'utilisation de la réflexion aux cas suivants:
Dans tous les autres cas, je suggérerais de trouver une approche qui évite la réflexion. Définir une interface avec la ou les méthodes appropriées et l'implémenter sur l'ensemble des classes sur lesquelles vous souhaitez appeler les méthodes est généralement suffisant pour résoudre les cas les plus simples.
la source
La réflexion est juste une autre forme de méta-programmation, et tout aussi valide, que les paramètres basés sur le type que vous voyez dans la plupart des langues de nos jours. La réflexion est puissante et générique, et les programmes réflexifs représentent un ordre de maintenabilité élevé (lorsqu'ils sont utilisés correctement, bien sûr) et plus encore que les programmes purement orientés objet ou procéduraux. Oui, vous payez un prix basé sur la performance, mais je choisirais volontiers un programme plus lent, plus facile à maintenir dans de nombreux cas, voire dans la plupart des cas.
la source
Tout dépend sûrement de ce que vous essayez de réaliser.
Par exemple, j'ai écrit une application de vérification des supports qui utilise l'injection de dépendance pour déterminer le type de support (fichiers MP3 ou fichiers JPEG) à vérifier. Le shell devait afficher une grille contenant les informations pertinentes pour chaque type, mais il ne savait pas ce qu'il allait afficher. Ceci est défini dans l'assembly qui lit ce type de support.
Par conséquent, je devais utiliser la réflexion pour obtenir le nombre de colonnes à afficher, ainsi que leurs types et leurs noms, afin de pouvoir configurer correctement la grille. Cela signifiait également que je pouvais mettre à jour la bibliothèque injectée (ou en créer une nouvelle) sans modifier aucun autre code ou fichier de configuration.
La seule autre manière aurait été d'avoir un fichier de configuration qui aurait besoin d'être mis à jour lorsque je changerais de type de média en cours de vérification. Cela aurait introduit un autre point d'échec pour l'application.
la source
La réflexion est un outil formidable si vous êtes un auteur de bibliothèque et n’avez donc aucune influence sur les données entrantes. Une combinaison de réflexion et de méta-programmation peut permettre à votre bibliothèque de travailler de manière transparente avec des appelants arbitraires, sans avoir à passer par des étapes de génération de code, etc.
J'essaie toutefois de décourager toute réflexion dans le code de l' application ; au niveau de l'application, vous devez utiliser différentes métaphores - interfaces, abstraction, encapsulation, etc.
la source
La réflexion est fantastique pour créer des outils pour les développeurs.
Comme cela permet à votre environnement de construction d’inspecter le code et de générer potentiellement les outils appropriés pour manipuler / init inspecter le code.
En tant que technique de programmation générale, cela peut être utile, mais il est plus fragile que la plupart des gens ne l’imaginent.
Une utilisation vraiment intéressante pour la réflexion (IMO) est qu’il est très simple d’écrire une bibliothèque de streaming générique (tant que votre description de classe ne change pas (elle devient alors une solution très fragile)).
la source
L'utilisation de la réflexion est souvent nuisible dans les langages OO si elle n'est pas utilisée avec une grande conscience.
J'ai perdu le compte du nombre de mauvaises questions que j'ai vues sur les sites StackExchange où
Voici sont des exemples typiques.
La plupart du point de OO est que
Si, à un moment quelconque de votre code, le point 2 n'est pas valide pour un objet que vous avez été passé, alors un ou plusieurs d'entre eux sont vrais.
Les développeurs peu qualifiés ne comprennent tout simplement pas cela et croient qu'on peut transmettre n'importe quoi dans n'importe quelle partie de leur code et qu'ils font ce qu'ils veulent à partir d'un ensemble de possibilités (codées en dur). Ces idiots utilisent beaucoup la réflexion .
Pour les langages orientés objet, la réflexion ne devrait être nécessaire que dans la méta-activité (chargeurs de classes, injection de dépendance, etc.). Dans ces contextes, il est nécessaire de réfléchir car vous fournissez un service générique pour faciliter la manipulation / configuration du code dont vous ne connaissez rien pour une bonne et légitime raison. Dans presque toutes les situations, si vous souhaitez réfléchir, vous faites quelque chose de mal et vous devez vous demander pourquoi ce morceau de code n'en sait pas assez sur l'objet qui lui a été transmis.
la source
Une alternative, dans les cas où le domaine des classes réfléchies est bien défini, consiste à utiliser la réflexion avec d'autres métadonnées pour générer du code , au lieu d'utiliser la réflexion au moment de l'exécution. Je le fais en utilisant FreeMarker / FMPP; il y a beaucoup d'autres outils à choisir. L'avantage, c'est que vous vous retrouvez avec du "vrai" code qui peut facilement être débogué, etc.
En fonction de la situation, cela peut vous aider à créer du code beaucoup plus rapide - ou juste beaucoup de code. Cela évite les inconvénients de la réflexion:
mentionné plus tôt.
Si la réflexion vous donne l'impression de tricher, c'est peut-être parce que vous vous basez sur beaucoup de conjectures dont vous n'êtes pas sûr, et que votre intestin vous avertit que c'est risqué. Assurez-vous de fournir un moyen d'améliorer les métadonnées inhérentes à la réflexion avec vos propres métadonnées, où vous pourrez décrire toutes les bizarreries et tous les cas particuliers des classes du monde réel que vous pourriez rencontrer.
la source
Ce n'est pas de la triche, mais comme tout outil, il devrait être utilisé pour ce qu'il est censé résoudre. La réflexion, par définition, vous permet d'inspecter et de modifier le code par le biais de code; Si c'est ce que vous devez faire, alors la réflexion est l'outil indispensable. La réflexion est centrée sur le méta-code: code qui cible le code (par opposition au code normal qui cible les données).
Les classes génériques d’interface de service Web constituent un exemple d’utilisation judicieuse de la réflexion: une conception typique consiste à séparer la mise en œuvre du protocole de la fonctionnalité de charge utile. Vous avez donc une classe (appelons-la
T
) qui implémente votre charge utile, et une autre qui implémente le protocole (P
).T
est assez simple: pour chaque appel que vous voulez faire, écrivez simplement une méthode qui fait ce qu’elle est supposée faire.P
Toutefois, vous devez mapper les appels de service Web sur les appels de méthode. Rendre ce mappage générique est souhaitable, car il évite les redondances et estP
hautement réutilisable. Reflection fournit les moyens d'inspecter une classeT
au moment de l'exécution et d'appeler ses méthodes en fonction de chaînes passéesP
via le protocole de service Web, sans aucune connaissance de la compilation lors de la compilation.T
. En utilisant la règle 'code about code', on peut affirmer que la classeP
a le code en classeT
dans ses données.Pourtant.
Reflection vous fournit également des outils permettant de contourner les restrictions du système de types du langage. En théorie, vous pouvez transmettre tous les paramètres en tant que type
object
et appeler leurs méthodes par réflexions. Voilà, le langage censé imposer une discipline de typage statique forte se comporte désormais comme un langage typé dynamiquement avec une liaison tardive, à la différence près que la syntaxe est beaucoup plus élaborée. Chaque exemple d'un tel modèle que j'ai vu jusqu'à présent a été un sale jeu et, invariablement, une solution dans le système de types de langue aurait été possible, et aurait été plus sûre, plus élégante et plus efficace à tous égards. .Il existe quelques exceptions, telles que les contrôles d'interface graphique pouvant être liés aux données à différents types de sources de données non liées; Exiger que vos données implémentent une certaine interface afin que vous puissiez lier les données n'est pas réaliste, et le programmeur n'a pas non plus à implémenter d'adaptateur pour chaque type de source de données. Dans ce cas, il est plus utile d’utiliser la réflexion pour détecter le type de source de données et d’ajuster la liaison de données.
la source
Un problème que nous avons eu avec Reflection est quand nous avons ajouté Obfuscation au mélange. Toutes les classes reçoivent de nouveaux noms et le chargement d'une classe ou d'une fonction par son nom cesse de fonctionner.
la source
Cela dépend totalement. Un exemple de chose qui serait difficile à faire sans réflexion serait de répliquer ObjectListView . Il génère également du code IL à la volée.
la source
La réflexion est la principale méthode de création de systèmes basés sur des conventions. Je ne serais pas surpris de constater qu'il est fortement utilisé dans la plupart des frameworks MVC. C'est un composant majeur dans les ORM. Les chances sont, vous utilisez déjà des composants construits avec elle tous les jours.
L'alternative pour une telle utilisation est la configuration, qui présente son propre ensemble d'inconvénients.
la source
La réflexion peut permettre d'atteindre des objectifs impossibles à réaliser autrement.
Par exemple, considérez comment optimiser ce code:
Il y a un test coûteux en plein milieu de la boucle interne, mais son extraction nécessite de réécrire la boucle une fois pour chaque opérateur. La réflexion nous permet d’obtenir des performances équivalentes à celles de l’extraction de ce test, sans répéter la boucle une douzaine de fois (sans pour autant sacrifier la facilité de maintenance). Il suffit de générer et de compiler la boucle dont vous avez besoin à la volée.
En fait, j'ai optimisé cette situation , même si la situation était un peu plus compliquée et les résultats ont été étonnants. Une amélioration de l'ordre de grandeur des performances et moins de lignes de code.
(Remarque: au départ, j'ai essayé l'équivalent de passer un Func à la place d'un caractère, ce qui était légèrement meilleur, mais presque pas la réflexion 10x obtenue.)
la source
Aucun moyen de tricher ... Cela permet plutôt aux serveurs d'applications d'exécuter les classes créées par l'utilisateur avec le nom de leur choix, offrant ainsi une flexibilité à l'utilisateur, pas de le tromper.
Et si vous voulez voir le code de n’importe quel fichier .class (en Java), plusieurs décompilateurs sont disponibles gratuitement!
la source