2 votes

Java Reflection : un mauvais modèle ?

Disons que j'ai beaucoup de classes similaires (des unités dans un RTS dans cet exemple), c'est-à-dire que la classe Unit et les sous-classes UnitA , UnitB , UnitC etc.

Toutes les classes Unit ont le constructeur suivant (y compris Unit)

public class UnitX {
    public UnitX(FileReader fr) {
         ...read parameters for constructing the unit...
    }
}

Mon fichier contenant les paramètres a la forme

UnitX params
UnitY params
....

et la création d'une liste de toutes les unités d'un fichier se ferait par une boucle de type "while".

Class[] params = {FileReader.class};
while(fr has more to read) {
    String unitType = fr.getString();
    Unit u = (Unit)
java.lang.reflect.Constructor constr = Class.forName(unitType).getConstructor(params);
    Unit u = (Unit)constr.newInstance(new Object[]{fr});
    list.add(u);
}

Je me suis rendu compte que j'utilise très souvent ce modèle lorsque je crée des objets à partir de fichiers. Ma question est la suivante : est-ce un mauvais modèle ? Existe-t-il une meilleure façon de procéder ?

3voto

ewernli Points 23180

Qu'un cas pour le modèle d'usine :

java.lang.reflect.Constructor constr = Class.forName(unitType).getConstructor(params);
Unit u = (Unit)constr.newInstance(new Object[]{fr});

pourrait être transformé en

Unit u = UnitFactory.create( unitType, fr );

L'usine est alors une liste de "if/else".

2voto

mdma Points 33973

Le code lui-même est bon. Puisque les constructeurs ne peuvent pas faire partie d'une interface codifiée traditionnelle, la meilleure chose à faire est l'interface réfléchie cohérente.

Cependant, si vous répétez ce code à de nombreux endroits, ce n'est pas très bon. Vous pourriez essayer de centraliser cela dans une sorte de fabrique ou de constructeur qui fournit des noms d'unités à partir du fichier, avec les paramètres définis pour cette unité, et l'associer à une implémentation de gestionnaire qui instancie l'unité avec les paramètres fournis via une UnitFactory. L'UnitFactory utilise la réflexion pour instancier l'unité nommée et lui fournir les paramètres.

Cela permet la réutilisation, et découple la lecture du fichier de l'instanciation, et la méthode d'instanciation.

1voto

tweber Points 751

Je pense que votre mise en œuvre est correcte. Une autre approche : le fichier texte est une forme simple de DSL (langage spécifique au domaine)

Vous pourriez passer à un langage plus dynamique compatible avec le jvm. Les langages dynamiques comme groovy (mon préféré ;-) ), javascript (Rhino,...), BeanShell, jython, ... peuvent plus facilement être utilisés pour implémenter des langages spécifiques au domaine (DSL). Pour des DSL plus complexes, vous pouvez jeter un coup d'oeil au projet eclipse XText.

0voto

krock Points 13537

Il s'agit d'une sérialisation simple et réduite. Je dirais que c'est très bien si cela correspond à vos besoins.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X