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 :

des enum sécurisés et propres


Sujet :

Langage Java

  1. #1
    Membre éclairé
    Avatar de JMLLB
    Inscrit en
    Septembre 2006
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 285
    Par défaut des enum sécurisés et propres
    J'ai un petit soucis avec les enums. Je n'arrive pas à trouver une solution qui me convienne pleinement.

    Pour l'instant j'utilise ce genre de chose:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public static final int SEASON_WINTER  = 0;
    public static final int SEASON_SPRING   = 1;
    public static final int SEASON_SUMMER = 2;
    public static final int SEASON_FALL      = 3;
    .
    .
    .
    int x=SEASON_WINTER;
    mais c'est pas terrible car ne me garanti que les valeurs sont bien distinctes.

    Quand à la variante suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public static class season{
      public static int winter()   {return 0;}
      public static int spring()   {return 1;}
      public static int summer() {return 2;}
      public static int fall()       {return 3;}
    }
    .
    .
    .
    int x=season.winter();
    c'est à peu de chose près la même chose.

    Je pensai avoir trouvé mon bonheur avec enum qui fleurait bon le c.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    enum Season { WINTER, SPRING, SUMMER, FALL }
    .
    .
    .
    int x=Season.WINTER.getOrdinal();
    Mais je ne peux pas utiliser directement Season.WINTER comme un int.
    Et le getOrdinal() est un peu lourdot.

    Je pense donc que je passe à côté de qqchose.
    Merci de me dire quoi.

  2. #2
    Membre chevronné Avatar de schniouf
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2003
    Messages : 382
    Par défaut
    Tu mets ta variable x en type Season :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Season x = Season.WINTER ;

  3. #3
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par schniouf
    Tu mets ta variable x en type Season :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Season x = Season.WINTER ;
    +1

    Et bien sur les enum peuvent être utilisées directement dans un switch



    Citation Envoyé par JMLLB
    Je pensai avoir trouvé mon bonheur avec enum qui fleurait bon le c.
    Ca fleure bon le C, mais cela reste de l'Orienté Objet puisque le type enum correspond à un objet (avec éventuellement constructeurs, méthodes et attributs).


    a++

  4. #4
    Membre éclairé
    Avatar de JMLLB
    Inscrit en
    Septembre 2006
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 285
    Par défaut
    Citation Envoyé par schniouf
    Tu mets ta variable x en type Season :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Season x = Season.WINTER ;
    Ok, ok!

    Mais lorsque tu n'as pas le choix du typage de ta variable?
    Dans le cas où elle peut-être affectée par plusieurs enum où tout simplement qu'elle se modifie via un accesseur qui t'impose un type.

    Pense pas que le cast explicite soit sans risque.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int x = (int) Season.WINTER ;

  5. #5
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par JMLLB
    Pense pas que le cast explicite soit sans risque.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int x = (int) Season.WINTER ;
    Est-ce que tu fais du code du genre:
    Je ne pense pas... Donc pourquoi veux-tu faire de même pour int <- enum ?

  6. #6
    Membre éclairé
    Avatar de JMLLB
    Inscrit en
    Septembre 2006
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 285
    Par défaut
    Citation Envoyé par ®om
    Est-ce que tu fais du code du genre:
    Je ne pense pas... Donc pourquoi veux-tu faire de même pour int <- enum ?
    Je n'ai aucune intention de faire des casts trans-genres.
    Mon intention était juste de mettre en évidence que là où j'aurai besoin d'un int, je me retrouve avec un objet.
    Et qu'il n'y a pas de transcodage immédiat et syntaxement léger entre les deux.

    Dans le cas de figure où on n'a pas la maitrise de la totalité du développement,
    on ne peut pas imposer l'utilisation d'enum sur les ressources qu'on utilise.

    Par exemple, mettons que je souhaite gérer l'accès des JComponent dans un JTabbedPane via un enum.
    La grande majorité des méthodes du JTabbedPane utilisent l'index du JTabbedPane qui n'est autre qu'un int.
    Utiliser un enum m'impose une syntaxte lourde car je doit manipuler des int.
    Dans ce cas de figure, j'utilise plutôt un set de constantes par soucis de facilité,
    alors que : fonctionnellement je devrais utiliser un enum.

    Ma question est donc la suivante: dans ce cas de figure où l'on doit utiliser des int,
    existe t'il une solution aussi sécurisé que les enums et aussi "fluide" que des constantes?


    PS: il va sans dire que l'exemple donné impose une utilisation "statique" du JTabbedPane
    (pas de suppression ni d'ajout en cours d'utilisation) sous peine d'avoir des indices abérrants.

  7. #7
    Membre émérite Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Par défaut
    je suis peux être a coté de la plaque mais je vais proposer quelquechose qui me semble tout con

    A coté de tes enum, tu peux definir une methode qui te converti ton enum en int.

  8. #8
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par benratti
    je suis peux être a coté de la plaque mais je vais proposer quelquechose qui me semble tout con

    A coté de tes enum, tu peux definir une methode qui te converti ton enum en int.
    Je ne trouve pas ca con du tout... au contraire !

    De plus cela existe déjà avec la méthode ordinal(). Le seul défaut vient du fait que cette dernière est basé sur l'ordre des valeurs de l'enum et que tu ne peux pas modifier les valeurs.

    Mais rien n'empêche d'utiliser un attribut et un accesseur (comme je l'ai dit une enum est un Object ) :

    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
    enum MonEnum {
     
    	// Les valeurs de l'énumération :
     
    	SEASON_WINTER(1),
    	SEASON_SPRING(2),
    	SEASON_SUMMER(3),
    	SEASON_FALL(4);
     
    	/** Valeur entière correspondant : */
    	private final int intValue;
     
    	MonEnum(int intValue) {
    		this.intValue = intValue;
    	}
     
    	public int intValue() {
    		return this.intValue;
    	}
    }
    Ce qui permettrait de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int x = SEASON_FALL.intValue();
    a++

  9. #9
    Membre éclairé
    Avatar de JMLLB
    Inscrit en
    Septembre 2006
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 285
    Par défaut Conclusion
    Ok, Ok! J'arrête! Je pense que l'on a fait le tour de la question.
    Je vais arrêter de me plaindre sur la lourdeur de la syntaxte et utiliser la solution getOrdinal(), soit la troisième option que je citais en début de discussion. Au moins maintenant je suis sur qu'il n'y pas de manière plus simple de faire les choses.

    merci à tous pour vos avis éclairés

    PS:

    De plus cela existe déjà avec la méthode ordinal(). Le seul défaut vient du fait que cette dernière est basé sur l'ordre des valeurs de l'enum et que tu ne peux pas modifier les valeurs.
    Ce défaut a néanmoins une qualité associé non négligeable, il assure par construction l'unicité de chaque valeur.
    Or, à moins que je ne maitrise pas complétement la classe enum (ce qui est d'ailleur le cas...) rien ne garanti que la valeur retournée par intValue est une clée unique. Et dans certain cas (pas tous) cela peut être génant.

  10. #10
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 913
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 913
    Billets dans le blog
    54
    Par défaut
    Citation Envoyé par JMLLB
    Or, à moins que je ne maitrise pas complétement la classe enum (ce qui est d'ailleur le cas...) rien ne garanti que la valeur retournée par intValue est une clée unique. Et dans certain cas (pas tous) cela peut être génant.
    Dans ce cas c'est une erreur dans la definition des valeurs de cette enumeration, un defaut de programmation de la methode intValue() ou un manque dans sa documentation ; donc une erreur venant de toi. Les enums formant un ensemble fini de valeur pre-definies, non-extensible et sans possibilite de re-definition, si jamais cette methode (telle que definie par adiGuba) retourne un entier identique pour 2 valeurs de l'enum differentes, c'est bien que tu t'es trompe en definissant les dites-valeur plus haut dans le code de l'enum puisque C'EST TOI MEME QUI DEFINIT CE PARAMETRE LORS DE LEUR INITIALISATION et ce AVANT la compilation.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  11. #11
    Membre éclairé
    Avatar de JMLLB
    Inscrit en
    Septembre 2006
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 285
    Par défaut Errare humanum est!
    ...c'est bien que tu t'es trompe en definissant les dites-valeur plus haut dans le code de l'enum puisque C'EST TOI MEME QUI DEFINIT CE PARAMETRE LORS DE LEUR INITIALISATION et ce AVANT la compilation.
    C'est bien là mon propos! Je n'ai pas la prétention d'être infaillible et j'en ai la preuve tout les jours.
    J'ai suffisement vu de set constantes vivre leur vie, être retouchés au cours de maintenances correctives par plein d'intervenants différents avec dans certain cas des doublons et des trous dans les valeurs pour être un fervant partisant des enums.
    A chaque fois que j'ai le choix entre faire confiance au langage et me faire confiance, je fais confiance au langage.
    Non pas que je n'ai pas confiance en moi, mais parceque le développement n'est pas une activité personnelle et instantanée mais une activité de groupe et prolongée.
    On connait rarement les autres intervenants et on ne connait pas forcément le soft qu'on modie, ni d'ailleurs la durée de vie réelle du logiciel.

    Ce que je souligne, c'est que cette approche n'apporte rien en terme de sécurisation par rapport à la définition de constantes.
    Si on doit choisir cette option, c'est pour être plus "orienté objet" mais pas pour rendre le code plus sûr.

  12. #12
    Membre chevronné Avatar de schniouf
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2003
    Messages : 382
    Par défaut
    Citation Envoyé par JMLLB
    De plus cela existe déjà avec la méthode ordinal(). Le seul défaut vient du fait que cette dernière est basé sur l'ordre des valeurs de l'enum et que tu ne peux pas modifier les valeurs.
    Ce défaut a néanmoins une qualité associé non négligeable, il assure par construction l'unicité de chaque valeur.
    Oui, mais de la même manière que quelqu'un qui va reprendre ton code peut modifier les valeurs entières, cette même personne peut aussi changer l'ordre des enums... auquel cas la fonction ordinal() ne te donnera plus le même résultat !

  13. #13
    Membre éclairé
    Avatar de JMLLB
    Inscrit en
    Septembre 2006
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 285
    Par défaut
    Citation Envoyé par schniouf
    Oui, mais de la même manière que quelqu'un qui va reprendre ton code peut modifier les valeurs entières, cette même personne peut aussi changer l'ordre des enums... auquel cas la fonction ordinal() ne te donnera plus le même résultat !
    Il est sûr qu'il n'existe pas de garantie absolue en terme de maintenance, mais l'unicité de chaque valeur est déjà bon à prendre, surtout si la valeur n'a pas de signification en soit (ce qui n'est malheureusment pas le cas de mon exemple).

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 94
    Par défaut
    Même si c'est un lourd pour pas forcément grand chose, si tu veux fixer les valeurs et être sûr de l'unicité d'une valeur tu peux toujours rajouter une couche par dessus, du genre :

    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
    29
    30
    31
    32
    33
    34
    35
    class MonEnumController {
    	private static Set<Integer> listeValeur = new HashSet<Integer>();
    	private static boolean error = false;
     
    	public static boolean hasError(){
    		return error;
    	}
     
    	enum MonEnum {
     
    		// Les valeurs de l'énumération :
    		SEASON_WINTER(1),
    		SEASON_SPRING(2),
    		SEASON_SUMMER(3),
    		SEASON_FALL(4);
     
    		/** Valeur entière correspondant : */
    		private final int intValue;
     
    		MonEnum(int intValue){
    			if (listeValeur.contains(intValue)){
    				error = true;
    				this.intValue = -1;
    			}
    			else{
    				this.intValue = intValue;
    				listeValeur.add(intValue);
    			}
    		}
     
    		public int intValue() {
    			return this.intValue;
    		}
    	}
    }

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

Discussions similaires

  1. Comment gérer des sous ensembles avec des "enum" ?
    Par ogattaz dans le forum Langage
    Réponses: 2
    Dernier message: 30/05/2007, 11h29
  2. Une solution pour faire des enums dynamique ?
    Par n!co dans le forum Langage
    Réponses: 7
    Dernier message: 16/12/2006, 15h44
  3. Cette page contient des éléments sécurisés et non sécurisés
    Par bigsister dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 26/04/2005, 15h01
  4. chercher des données dans sa propre requete...
    Par shadowbob dans le forum Requêtes
    Réponses: 4
    Dernier message: 27/06/2004, 18h13

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