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

Entrée/Sortie Java Discussion :

Proposer des options (fichier properties ?)


Sujet :

Entrée/Sortie Java

  1. #1
    Membre éprouvé

    Inscrit en
    Janvier 2009
    Messages
    467
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 467
    Points : 1 253
    Points
    1 253
    Billets dans le blog
    2
    Par défaut Proposer des options (fichier properties ?)
    Bonjour,

    Je cherche à proposer différentes options pour l’exécution d’un programme. Pour simplifier mettons qu’il s’agit de 3 manières (manière 1, manière 2, manière 3) de faire un calcul.

    Pour le moment je fonctionne comme cela :

    J’ai une énumération qui défini les manières disponibles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public enum ManieresDeCalcul {MANIERE_1, MANIERE_2, MANIERE_3}
    Et dans ma classe principale j’ai une fonction calcule() qui attend la manière comme paramètre. Dans cette méthode, à l’aide d’un switch, j’utilise la méthode qui me convient :
    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
    public int calcule(ManieresDeCalcul maniere) {
    	int resultat;
    	resultat = 0;
     
    	switch(maniere) {
    	case MANIERE_1 :
    		//code pour la maniere de calcul 1 => resultat
    		break;
    	case MANIERE_2 :
    		//code pour la maniere de calcul 2
    		break;	
    	case MANIERE_3 :
    		//code pour la maniere de calcul 3
    		break;
    	}
     
    	return resultat;
    }
    Première question : s’agit t’il d’une bonne méthode pour résoudre ce type de problème ou y a t’il d’autre moyen plus élégant ?


    * * *

    Ensuite, j’aimerais avoir la possibilité d’avoir un comportement par défaut. Il me semble que cela ne pose pas de problème, je n’ai qu’à avoir la même méthode sans paramètres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public int calcule() {
    	return calcule(ManieresDeCalcul.MANIERE_1);
    }
    (en considérant que la MANIERE_1 est celle par défaut)

    * * *

    Maintenant je souhaiterais pouvoir définir quelle va être la méthode par défaut à utiliser (un fichier texte me semble assez approprié).

    Il me semble que Java propose un mécanisme de fichier Properties pour répondre à ce type de problème.

    S'agit il d'une bonne idée (sinon comment faire autrement) ?
    Où puis je trouver un exemple, ou de la doc pour en savoir plus ?


    Est-ce que dans le fichier properties je peux forcer le fait de devoir avoir une valeur contenue dans une énumération (ou faut-il que je refasse un mapping de type String -> Valeur de l’Enum)


    Je voudrais utiliser une méthode standard et utilisée par tous, histoire d'éviter de réinventer une roue qui doit déjà exister en standard...


    Merci

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 121
    Points : 136
    Points
    136
    Par défaut
    Autres solutions...
    Commence par définir une interface de calcul que tu implémentes dans une classe séparée pour chaque manière de calcul:

    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
     
    public interface ManiereDeCalcul {
    	int calcul();
    }
     
    public class ManiereDeCalcul1 implements ManiereDeCalcul {
    	public int calcul() {
    		// TODO Premiere maniere de calcul
    		return 1;
    	}
    }
     
    public class ManiereDeCalcul2 implements ManiereDeCalcul {
    	public int calcul() {
    		// TODO 2e Premiere maniere de calcul
    		return 2;
    	}
    }
    Pour choisir le bon calcul en fonction de son nom tu peux utiliser une Map<String,ManiereDeCalcul> chargée statiquement...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import java.util.HashMap;
     
    public class MapCalculs extends HashMap<String, ManiereDeCalcul>{
    	public MapCalculs() {
    		put("ManiereDeCalcul1",new ManiereDeCalcul1());
    		put("ManiereDeCalcul2",new ManiereDeCalcul2());
    		//...etc...
    	}
    }
    Tu peux aussi utiliser ton propre ClassLoader...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class CalculClassLoader extends ClassLoader {
    	public ManiereDeCalcul getManiereDeCalcul(String maniere) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    		Class<?> c=loadClass(maniere);
    		return (ManiereDeCalcul)c.newInstance();
    	}
    }
    public class Calcul {
    	int calcul(String nom) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    		return new CalculClassLoader().getManiereDeCalcul(nom).calcul();
    	}
    }
    Cà donne ...
    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 static void main(String[] args) {
    	// Appels via une Map 
    	MapCalculs mapCalculs=new MapCalculs();
    	System.out.println(mapCalculs.get("ManiereDeCalcul1").calcul());
    	System.out.println(mapCalculs.get("ManiereDeCalcul2").calcul());
     
    	// Appels via un classLoader
    	try {
    		System.out.println(new Calcul().calcul("ManiereDeCalcul1"));
    		System.out.println(new Calcul().calcul("ManiereDeCalcul2"));
    	} catch (Exception e) {
    		e.printStackTrace();
    	} 
    }

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Points : 1 419
    Points
    1 419
    Par défaut



    En mille fois plus simple : les enum SONT des classes (spéciales, certes, mais des classes quand même).

    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
    public enum ManieresDeCalcul {
      MANIERE_1 {
        public int calcul (String parametrePourCalcul) {
          return 1;
        }
      },
      MANIERE_2 {
        public int calcul (String parametrePourCalcul) {
          return 2;
        }
      },
      MANIERE_3 {
        public int calcul (String parametrePourCalcul) {
          return 3;
        }
      };
     
      public abstract int calcul (String parametrePourCalcul);
    }
    Et la méthode calcule (ManieresDeCalcul) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public int calcule (ManieresDeCalcul mdc) {
      String monParam = "mon param";
      int resultat = mdc.calcul(monParam);
    }
    On en profite pour éviter un switch ET une surcharge de classes (même si implicitement, il y en a).

  4. #4
    Membre éprouvé

    Inscrit en
    Janvier 2009
    Messages
    467
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 467
    Points : 1 253
    Points
    1 253
    Billets dans le blog
    2
    Par défaut
    Je vois que c'etait pas une question si stupide...

    Comment avec la méthode de dingoth, je peux stocker dans un fichier de paramétrage (a priori du texte) quelle doit être celle a utiliser par défaut ?

    Est ce que là aussi il y un moyen de retrouver de quel élément de l'énumération on parle ?

    J'imagine qu'il y a mieux que de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ManieresDeCalcul mdc;
    String mdcParDefaut;
    // on recherche (dans un fichier de config) la valeur par defaut -> mdcParDefaut
    if(mdcParDefaut.contentEquals("MANIERE_1")) {
       mdc = ManieresDeCalcul.MANIERE_1;
    } else if(mdcParDefaut.contentEquals("MANIERE_2")) {
       mdc = ManieresDeCalcul.MANIERE_2;
    } else if(mdcParDefaut.contentEquals("MANIERE_3")) {
       mdc = ManieresDeCalcul.MANIERE_3;
    }
     
    return mdc;
    Merci pour vos réponses.

    .

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Points : 1 419
    Points
    1 419
    Par défaut
    Certainement, il y a mieux, et toujours grâce aux enum !


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ManieresDeCalcul mdc;
    String mdcParDefaut;
    // on recherche (dans un fichier de config) la valeur par defaut -> mdcParDefaut
     
    mdc = ManieresDeCalcul.valueOf(mdcParDefaut); 
    return mdc;
    Et paf, encore 5 lignes de parties !

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Points : 402
    Points
    402
    Par défaut
    dingoth je vois que vous apprécier énormément les enum
    Sinon à part les enum tu peux construire une application configurable à l'aide d'un fichier properties où
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    default=classe d'implémentation par défault
    maniere1=classe d'implémentation 1
    maniere2=classe d'implémentation 2
    Les classes d'implémentation doivent implémenter une certaine interface
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public insterface IManiere {
     void calcul(Object param);
    }
    Une classe Manager qui charge le properties et qui fait grosso modo
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IManiere maniere = (IManiere) Class.forName(properties.get(maniere));
    maniere.calcul(XXX);

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Points : 1 419
    Points
    1 419
    Par défaut
    Bah, ma philosophie est : "utilisons les outils que nous avons à notre disposition". Les enum ont été introduites en Java 5, et malheureusement trop peu de développeurs savent tout ce qu'elles permettent.

  8. #8
    Membre éprouvé

    Inscrit en
    Janvier 2009
    Messages
    467
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 467
    Points : 1 253
    Points
    1 253
    Billets dans le blog
    2
    Par défaut
    Franchement j'adore ces Enum, je trouve ça très propre...

    Un très grand merci à toi dingoth.

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Points : 1 419
    Points
    1 419
    Par défaut
    De rien !

    Notons toutefois que la méthode valueOf est très stricte : elle ne renverra une réponse que si le String donné est exactement (casse de caractère incluse) le nom programmatique de la variable. Donc si tu introduis ce nom dans un fichier properties, sois certain de ne pas refactoriser l'enum en changeant le nom de la variable.

  10. #10
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par dingoth Voir le message
    Notons toutefois que la méthode valueOf est très stricte : elle ne renverra une réponse que si le String donné est exactement (casse de caractère incluse) le nom programmatique de la variable. Donc si tu introduis ce nom dans un fichier properties, sois certain de ne pas refactoriser l'enum en changeant le nom de la variable.
    Tu peux toujours proposer ta propre version un peu moins contraignante, et avec une valeur par défaut. Par exemple :

    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
    public enum ManieresDeCalcul {
     
    	// ...
     
    	public abstract int calcul(String parametrePourCalcul);
     
    	public static ManieresDeCalcul getByName(String name) {
    		for (ManieresDeCalcul calcul : ManieresDeCalcul.values()) {
    			if (calcul.name().equalsIgnoreCase(name)) {
    				return calcul;
    			}
    		}
    		return MANIERE_1;
    	}
    }

    Citation Envoyé par jmini Voir le message
    Franchement j'adore ces Enum, je trouve ça très propre...
    En effet !

    Mais il faut quand même garder en tête que du coup les méthodes de calcul sont limité, que tu ne peux pas donc en ajouter dynamiquement, et que tu ne peux pas avoir différentes instances...


    Tu peux éviter cela en utilisant en cumulant les deux solutions, c'est à dire en utilsiant à la fois une interface et une enum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface Calcul {
    	public int calcul (String parametrePourCalcul);
    }
    Qui sera implémenté par ton enum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public enum ManieresDeCalcul implements Calcul {
    L'intérêt, c'est qu'en utilisant l'interface Calcul au lieu de l'enum, ton code reste ouvert à des modifications "externes" sans que cela ne rentre obligatoirement dans l'enum. Ainsi, l'enum représente plutôt les manières de calcul standard ou par défaut, mais tu restes libre de proposer de nouvelles implémentations sans avoir forcément à modifier l'enum...


    C'est une solution que je trouve très élégante, et qui a été adopté par le package java.nio.file de Java 7...




    Après libre à toi de recherche le mode de calcul dans l'enum ou via une implémentation spécifique via la reflection, ce qui se révèle assez facile à implémenter :
    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
    	public static Calcul getCalcul(String name) {
     
    		// On recherche d'abord l'enum via son nom :
    		for (ManieresDeCalcul calcul : ManieresDeCalcul.values()) {
    			if (name.equalsIgnoreCase(calcul.name())) {
    				return calcul;
    			}
    		}
     
    		// Sinon on considère qu'il s'agit d'un nom de classe :
    		try {
    			Class<?> clazz = Class.forName(name);
    			// Et qu'elle implémente bien l'interface Calcul :
    			if (Calcul.class.isAssignableFrom(clazz)) {
    				return (Calcul) clazz.newInstance();
    			}
    		} catch (Exception e) {
    			// En cas d'erreur lors de la reflection :
    			throw new IllegalArgumentException(name, e);
    		}
    		// On ne trouve rien de correspondant :
    		throw new IllegalArgumentException(name);
    	}

    a++

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Points : 402
    Points
    402
    Par défaut
    Heo agiduba tu m'a piqué mon idée sauf que moi je n'utilise pas d'enum ce qui peut être utilisé avec n'importe quel version de java
    le tien->
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    try {
    			Class<?> clazz = Class.forName(name);
    			// Et qu'elle implémente bien l'interface Calcul :
    			if (Calcul.class.isAssignableFrom(clazz)) {
    				return (Calcul) clazz.newInstance();
    			}
    		} catch (Exception e) {
    			// En cas d'erreur lors de la reflection :
    			throw new IllegalArgumentException(name, e);
    		}
    		// On ne trouve rien de correspondant :
    		throw new IllegalArgumentException(name);
    	}
    le mien où j'ai oublié d'instancier la classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IManiere maniere = (IManiere) Class.forName(properties.get(maniere));
    maniere.calcul(XXX);
    A++

  12. #12
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par hibour Voir le message
    Heo agiduba tu m'a piqué mon idée sauf que moi je n'utilise pas d'enum ce qui peut être utilisé avec n'importe quel version de java
    J'ai bien précisé que c'était une solution mixte entre les deux
    Citation Envoyé par adiGuba
    en cumulant les deux solutions
    L'intérêt (lorsqu'on peut les utiliser bien sûr), c'est que les enums facilitent certaines en évitant les duplications d'instances et en facilitant l'auto-complétion


    a++

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Points : 402
    Points
    402
    Par défaut
    Ok chef pas de soucis. Les enum c'est bien quand les états sont fixe sinon c'est assez figé.
    A++

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/07/2007, 08h03
  2. Charger le path des fichiers properties
    Par yanis97 dans le forum Langage
    Réponses: 1
    Dernier message: 30/11/2006, 20h54
  3. Réponses: 5
    Dernier message: 15/09/2006, 14h26
  4. Placer les requetes dans des fichiers properties
    Par rach375 dans le forum JDBC
    Réponses: 5
    Dernier message: 11/07/2006, 15h04
  5. [Fichiers properties] Créer des rubriques
    Par MiJack dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 30/09/2005, 19h57

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