IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

[Java5] Types énumérés et analyse syntaxique


Sujet :

Langage Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Transports

    Informations forums :
    Inscription : Août 2012
    Messages : 8
    Points : 7
    Points
    7
    Par défaut [Java5] Types énumérés et analyse syntaxique
    Bonjour à tous,



    Je cherche à rendre générique le fait d'analyser des fichiers plats permettant de valoriser plusieurs énumérations dont la forme serait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    public enum InformationFonctionnelle1
    {
      PREMIERE_VALEUR ("texte1"), 
      DEUXIEME_VALEUR ("texte2");
     
      private static Map<String, InfiormationFonctionnelle1> associations;
     
      // Avec le constructeur qui va bien et la méthode statique permettant de récuperer l'énumération en fct de la chaine de caractères
     
      // Méthode qui ressemble à ceci : 
      public static InformationFonctionnelle1 deChaine (String chaine)
      {
        return associations.get(chaine);
      }
    }
    Ma problématique est que j'ai une douzaine d'énumérations de ce type et une structure d'analyseur syntaxique à reprendre.


    L'analyse syntaxique de mon projet se fait notamment par le biais de classes réalisant l'interface suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public interface Champ<T> 
    {
      T parse(final String value) throws ParseurException;
    }
    dont on a par exemple la réalisation suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public class ChampInteger implements Champ<Integer> 
    {
        public Integer parse(final String champ) throws ParseurException {
            if (StringUtils.isNotBlank(champ)) {
                try {
                    return Integer.parseInt(StringUtils.trim(champ));
                } catch (final NumberFormatException e) {
                    throw new ParseurException("Le champ " + champ + " n'est pas un nombre entier");
                }
            }
            return null;
        }
    }

    Mon souhait serait d'ajouter une classe ChampEnum<E extends Enum<E>> réalisant le contrat Champ<E extends Enum<E>> (ou plus précisément la même chose où désigne une des quelques énumérations m'intéressant).


    Je pensais d'abord mettre en place une interface réalisée par mes énums pour y placer la méthode deChaine... mais étant une méthode statique, ça ne risque pas de fonctionner.

    J'ai beau tourner le problème dans tous les sens, je n'arrive pas à trouver une manière de spécifier de façon générique un type disposant d'une méthode statique deChaine(String)


    Quelqu'un aurait-il une suggestion ?
    Parce que là, je suis à quelques doigts de passer par des conversions explicites type par type ... ce que j'apprécierais d'éviter par soucis de maintenance.

  2. #2
    Membre éprouvé
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Points : 1 078
    Points
    1 078
    Par défaut
    Bonjour,

    tu peux utiliser une méthode dans ce goût-là:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
        public interface Valuable
        {
            String getValue();
        }
     
        public class ChampEnum<E extends Enum<?> & Valuable> implements ...
        {
     
            private final Class<E> type;
     
            public ChampEnum(final Class<E> type)
            {
                super();
                this.type = type;
            }
     
            public E getparse(final String value)
            {
                for (E instance : type.getEnumConstants())
                {
                    if (value.equals(instance.getValue()))
                    {
                        return instance;
                    }
                }
                return null;
            }
        }
    Avec cette solution, tes classes Enum devront étendre de l'interface Valuable afin de pouvoir accéder à la valeur textuelle. De plus, ta méthode deChaine n'est plus utilisée.

    Tu vas devoir créer N instances de ta classe ChampEnum: une par enum.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Transports

    Informations forums :
    Inscription : Août 2012
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Merci pour le retour ... et pour la notation & pour spécifier plusieurs "classes" mère, probablement l'élément qui me manquait pour finaliser la solution que tu proposes et à laquelle je pensais sans arriver à conclure.

    J'aurais préféré éviter la boucle sur les valeurs possibles... mais je crains de ne pas avoir le choix. (C'est toujours mieux que d'avoir une méthode par énum à convertir [et donc une classe réalisant l'interface Champ<T> par énumération pour conserver le modèle])


    Citation Envoyé par Deaf Voir le message
    Tu vas devoir créer N instances de ta classe ChampEnum: une par enum.
    Dans les faits, c'est un peu différent vu le cas d'application.




    (Je mettrai le [RESOLU] un peu plus tard, des fois que quelqu'un propose une solution sans la boucle sur les constantes énumérées )

  4. #4
    Membre éprouvé
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Points : 1 078
    Points
    1 078
    Par défaut
    Tu peux très bien revenir sur la méthode deChaine que tu avais, déclarée dans une interface qui remplacera la Valuable que j'avais proposé.

    Et au lieu d'une boucle, tu récupères la première valeur de l'énumération et tu appelles la méthode dessus.

    C'est pas l'idéal dans le sens où tu déclares une méthode non static alors qu'elle est static dans l'âme, mais ça évitera la boucle que tu sembles redouter.
    En plus ça te fait créer une Map par Enum avec le code qui va avec qui sera dupliqué joyeusement.

    C'est toi qui vois!

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Transports

    Informations forums :
    Inscription : Août 2012
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Ce n'est pas tant que je la redoute mais plus que j'ai l'impression qu'il y a certainement moyen de faire plus compact (les énumérations n'auront pas non plus 10 milliards de constantes chacune donc pas de problème de performance sous-jacent) tout en restant conforme à la logique objet (j'y avais pensé aussi à la méthode non statique).
    Mais la solution que tu proposes est probablement la seule compacte, générique et extensible à mon problème.


    Je me fais probablement une fausse idée vu que toutes les solutions auxquelles j'ai pu penser se sont heurtées à des limites structurelles du langage.

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 567
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 567
    Points : 21 633
    Points
    21 633
    Par défaut
    À la limite il y aurait bien la recherche par introspection de la méthode deChaine(), et son appel.
    C'est probablement ce qui a l'air le plus logique, mais :
    - le compilateur ne vérifiera pas l'existence de cette méthode deChaine(), c'est le runtime qui le fera.
    - l'introspection c'est quand même un peu verbeux, pas très compact.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Transports

    Informations forums :
    Inscription : Août 2012
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par thelvin Voir le message
    À la limite il y aurait bien la recherche par introspection de la méthode deChaine(), et son appel.
    C'est probablement ce qui a l'air le plus logique, mais :
    - le compilateur ne vérifiera pas l'existence de cette méthode deChaine(), c'est le runtime qui le fera.
    - l'introspection c'est quand même un peu verbeux, pas très compact.

    C'est par ailleurs plutôt coûteux en terme de performances si je ne m'abuse.
    Vu que l'analyse syntaxique concernée s'attaque à des lots d'environ 2 millions de lignes, si chaque enum doit faire l'objet d'une introspection, on n'est pas sortis de l'auberge.
    Ca commence à faire beaucoup d'arguments contre si on y ajoute la non sûreté sur l'existence de la méthode.

    Je vais retenir la première option.


    Finalement, j'avais envisagé toutes les options réalistes... ne me manquait qu'un petit outil syntaxique (le & pointé plus haut) pour mener la plus propre à terme.

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 567
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 567
    Points : 21 633
    Points
    21 633
    Par défaut
    Citation Envoyé par vaxyl Voir le message
    C'est par ailleurs plutôt coûteux en terme de performances si je ne m'abuse.
    Possiblement. Après, il faut voir si tu peux t'arranger pour ne chercher qu'une seule fois la Method de chaque classe concernée.

    Naturellement, la recherche de la Method, il faut ne la faire qu'une seule fois par type concerné. En voyant la tête de ton interface Champ, tu en as une instance pour chaque type parsable, ce n'est donc pas un problème.

    Citation Envoyé par vaxyl Voir le message
    Ca commence à faire beaucoup d'arguments contre si on y ajoute la non sûreté sur l'existence de la méthode.
    Ce n'est pas faux.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [c# 2.0][DEBUTANT] type énuméré
    Par dsr57 dans le forum C#
    Réponses: 2
    Dernier message: 13/10/2006, 17h03
  2. [D2005] Utilisation des types énumérés
    Par bouha dans le forum Delphi .NET
    Réponses: 2
    Dernier message: 21/07/2005, 23h21
  3. Réponses: 6
    Dernier message: 07/03/2005, 14h45
  4. Réponses: 7
    Dernier message: 02/06/2003, 09h38
  5. Transformer un caractère en type énuméré
    Par HT dans le forum Langage
    Réponses: 3
    Dernier message: 22/10/2002, 21h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo