Question

Récemment, je parlais de C++ à un collègue et je déplorais qu'il n'y ait aucun moyen de prendre une chaîne avec le nom d'un champ de classe et d'extraire le champ portant ce nom ;autrement dit, il manque de réflexion.Il m'a jeté un regard déconcerté et m'a demandé quand quelqu'un aurait besoin de faire une telle chose.

De mémoire, je n'avais pas de bonne réponse à lui donner, à part "hé, je dois le faire maintenant".Je me suis donc assis et j'ai dressé une liste de certaines des choses que j'ai réellement faites avec réflexion dans différentes langues.Malheureusement, la plupart de mes exemples proviennent de ma programmation Web en Python, et j'espérais que les gens ici auraient plus d'exemples.Voici la liste que j'ai dressée :

  1. Étant donné un fichier de configuration avec des lignes comme
    x = "Bonjour tout le monde !"
    y = 5,0
    définir dynamiquement les champs de certains config objet égal aux valeurs de ce fichier.(C'est ce que j'aurais aimé pouvoir faire en C++, mais je ne pouvais pas le faire.)

  2. Lors du tri d'une liste d'objets, triez en fonction d'un attribut arbitraire en fonction du nom de cet attribut à partir d'un fichier de configuration ou d'une requête Web.

  3. Lors de l'écriture d'un logiciel utilisant un protocole réseau, la réflexion vous permet d'appeler des méthodes basées sur les valeurs de chaîne de ce protocole.Par exemple, j'ai écrit un bot IRC qui traduirait
    !some_command arg1 arg2
    dans un appel de méthode actions.some_command(arg1, arg2) et imprimez quelle que soit cette fonction renvoyée sur le canal IRC.

  4. Lorsque j'utilisais la fonction __getattr__ de Python (qui ressemble un peu à method_missing dans Ruby/Smalltalk), je travaillais avec une classe avec beaucoup de statistiques, comme late_total.Pour chaque statistique, je voulais pouvoir ajouter _percent pour obtenir cette statistique en pourcentage du total des éléments que je comptais (par exemple, stats.late_total_percent).La réflexion a rendu cela très facile.

Alors, quelqu'un ici peut-il donner des exemples tirés de ses propres expériences de programmation de moments où la réflexion a été utile ?La prochaine fois qu'un collègue me demande pourquoi je « voudrais faire quelque chose comme ça », j'aimerais être mieux préparé.

Était-ce utile?

La solution

Je peux énumérer les utilisations suivantes pour réflexion :

  • Reliure tardive
  • Sécurité (code d'introspection pour des raisons de sécurité)
  • Analyse des codes
  • Saisie dynamique (la saisie en canard n'est pas possible sans réflexion)
  • Métaprogrammation

Quelques utilisations concrètes de la réflexion tirées de mon expérience personnelle :

  • Système de plugin développé basé sur la réflexion
  • Modèle de programmation orienté aspect utilisé
  • Analyse de code statique effectuée
  • Utilisation de divers frameworks d'injection de dépendances
  • ...

La réflexion est une bonne chose :)

Autres conseils

J'ai utilisé la réflexion pour obtenir des informations sur la méthode actuelle pour les exceptions, la journalisation, etc.

string src = MethodInfo.GetCurrentMethod().ToString();
string msg = "Big Mistake";
Exception newEx = new Exception(msg, ex);
newEx.Source = src;

au lieu de

string src = "MyMethod";
string msg = "Big MistakeA";
Exception newEx = new Exception(msg, ex);
newEx.Source = src;

C'est tout simplement plus facile pour l'héritage copier/coller et la génération de code.

Je suis maintenant dans une situation où j'ai un flux de XML arrivant sur le réseau et j'ai besoin d'instancier un objet Entity qui se remplira à partir des éléments du flux.Il est plus facile d'utiliser la réflexion pour déterminer quel objet Entity peut gérer quel élément XML plutôt que d'écrire une gigantesque instruction conditionnelle de maintenance cauchemardesque.Il existe clairement une dépendance entre le schéma XML et la façon dont je structure et nomme mes objets, mais je contrôle les deux donc ce n'est pas un gros problème.

Il arrive souvent que vous souhaitiez instancier dynamiquement et travailler avec des objets dont le type n'est pas connu avant l'exécution.Par exemple avec des OR-mappers ou dans une architecture plugin.Les frameworks moqueurs l'utilisent si vous souhaitez écrire une bibliothèque de journalisation et examiner dynamiquement le type et les propriétés des exceptions.

Si je réfléchis un peu plus longtemps, je pourrai probablement trouver plus d'exemples.

Je trouve la réflexion très utile si les données d'entrée (comme XML) ont une structure complexe qui est facilement mappée à des instances d'objet ou si j'ai besoin d'une sorte de relation "est une" entre les instances.

Comme la réflexion est relativement simple en Java, je l'utilise parfois pour des données simples (cartes clé-valeur) où je dispose d'un petit jeu de clés fixe.D'une part, il est simple de déterminer si une clé est valide (si la classe a un setter setKey(String data)), d'autre part, je peux changer le type des données d'entrée (textuelles) et masquer la transformation (par exemple, une simple conversion à int dans getKey()), afin que le reste de l'application puisse s'appuyer sur des données correctement saisies.Si le type d'une paire clé-valeur change pour un objet (par ex.form int pour flotter), je n'ai qu'à le modifier dans l'objet de données et ses utilisateurs, mais je n'ai pas besoin de garder à l'esprit de vérifier également l'analyseur.Ce n'est peut-être pas une approche judicieuse si les performances sont un problème...

Rédaction des répartiteurs.Twisted utilise les capacités de réflexion de Python pour distribuer les appels XML-RPC et SOAP.RMI utilise l'API de réflexion de Java pour la répartition.

Analyse de la ligne de commande.Création d'un objet de configuration basé sur les paramètres de ligne de commande transmis.

Lors de l'écriture de tests unitaires, il peut être utile d'utiliser la réflexion, même si je l'ai principalement utilisé pour contourner les modificateurs d'accès (Java).

J'ai utilisé la réflexion en C# lorsqu'il y avait une méthode interne ou privée dans le framework ou une bibliothèque tierce à laquelle je voulais accéder.

(Clause de non-responsabilité:Il ne s'agit pas nécessairement d'une bonne pratique, car les méthodes privées et internes peuvent être modifiées dans les versions ultérieures.Mais cela a fonctionné pour ce dont j'avais besoin.)

Eh bien, dans les langages à typage statique, vous voudriez utiliser la réflexion chaque fois que vous devez faire quelque chose de « dynamique ».Il est utile à des fins d'outillage (analyse des membres d'un objet).En Java, il est assez utilisé dans JMX et les proxys dynamiques.Et il existe des tonnes de cas ponctuels où c'est vraiment la seule voie à suivre (à peu près chaque fois que vous devez faire quelque chose que le compilateur ne vous laisse pas faire).

J'utilise généralement la réflexion pour le débogage.La réflexion peut afficher les objets du système plus facilement et avec plus de précision qu'un assortiment d'instructions imprimées.Dans de nombreux langages dotés de fonctions de première classe, vous pouvez même appeler les fonctions de l'objet sans écrire de code spécial.

Il existe cependant un moyen de faire ce que vous voulez (ed).Utilisez une table de hachage.Stockez les champs saisis par rapport au nom du champ.

Si vous le souhaitez vraiment, vous pouvez alors créer des fonctions Get/Set standard ou créer des macros qui le font à la volée. #define GetX() Get("X") genre de chose.

Vous pouvez même mettre en œuvre votre propre réflexion imparfaite de cette façon.

Pour l'utilisateur avancé, si vous pouvez compiler le code, il peut être possible d'activer la génération de sortie de débogage et de l'utiliser pour effectuer une réflexion.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top