Quelle est la meilleure façon d'implémenter les constantes en Java ?
Une approche que nous devrions vraiment éviter l'utilisation d'interfaces pour définir des constantes.
Créer une interface spécifiquement pour déclarer des constantes est vraiment la pire des choses : cela va à l'encontre de la raison pour laquelle les interfaces ont été conçues : définir le contrat des méthodes.
Même si une interface existe déjà pour répondre à un besoin spécifique, déclarer les constantes dans ces interfaces n'a vraiment aucun sens car les constantes ne devraient pas faire partie de l'API et du contrat fourni aux classes clientes.
Pour simplifier, nous avons grosso modo 4 approches valables .
Avec static final String/Integer
champ :
- 1) utiliser une classe qui déclare des constantes à l'intérieur mais pas seulement.
- 1 variante) créer une classe dédiée à la déclaration des constantes uniquement.
Avec Java 5 enum
:
- 2) déclarer l'enum dans une classe à but connexe (donc comme une classe imbriquée).
- 2 variante) créer l'enum comme une classe autonome (donc définie dans son propre fichier de classe).
TLDR : Quelle est la meilleure méthode et où se trouvent les constantes ?
Dans la plupart des cas, la méthode des enums est probablement plus fine que la méthode des static final String/Integer
chemin et personnellement, je pense que le static final String/Integer
ne devrait être utilisée que si nous avons de bonnes raisons de ne pas utiliser les enums.
Et sur l'endroit où nous devons déclarer les valeurs constantes, l'idée est de rechercher s'il existe une seule classe existante qui possède une cohésion fonctionnelle spécifique et forte avec des valeurs constantes. Si nous trouvons une telle classe, nous devons l'utiliser comme support de constantes. . Sinon, la constante ne doit être associée à aucune classe particulière.
static final String
/ static final Integer
contre enum
L'utilisation d'Enums est vraiment un moyen à considérer fortement.
Les Enums ont un grand avantage sur String
ou Integer
champ constant.
Ils fixent une contrainte de compilation plus forte. Si vous définissez une méthode qui prend l'enum comme paramètre, vous ne pouvez passer qu'une valeur d'enum définie dans la classe enum (ou null).
Avec String et Integer, vous pouvez les remplacer par n'importe quelle valeur de type compatible et la compilation se fera sans problème, même si la valeur n'est pas une constante définie dans le fichier static final String
/ static final Integer
champs.
Par exemple, ci-dessous deux constantes définies dans une classe comme static final String
champs :
public class MyClass{
public static final String ONE_CONSTANT = "value";
public static final String ANOTHER_CONSTANT = "other value";
. . .
}
Voici une méthode qui s'attend à avoir une de ces constantes comme paramètre :
public void process(String constantExpected){
...
}
Vous pouvez l'invoquer de la manière suivante :
process(MyClass.ONE_CONSTANT);
ou
process(MyClass.ANOTHER_CONSTANT);
Mais aucune contrainte de compilation ne vous empêche de l'invoquer de cette manière :
process("a not defined constant value");
Vous n'aurez l'erreur qu'au moment de l'exécution et seulement si vous effectuez à un moment donné un contrôle sur la valeur transmise.
Avec les enum, les vérifications ne sont pas nécessaires car le client ne peut que passer une valeur enum dans un paramètre enum.
Par exemple, voici deux valeurs définies dans une classe enum (donc constantes d'emblée) :
public enum MyEnum {
ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");
private String value;
MyEnum(String value) {
this.value = value;
}
...
}
Voici une méthode qui s'attend à avoir une de ces valeurs d'énumération comme paramètre :
public void process(MyEnum myEnum){
...
}
Vous pouvez l'invoquer de la manière suivante :
process(MyEnum.ONE_CONSTANT);
ou
process(MyEnum.ANOTHER_CONSTANT);
Mais la compilation ne vous permettra jamais de l'invoquer de cette manière :
process("a not defined constant value");
Où devons-nous déclarer les constantes ?
Si votre application contient une seule classe existante qui possède une cohésion fonctionnelle spécifique et forte avec les valeurs constantes, le 1) et le 2) semblent plus intuitifs.
En général, l'utilisation des constantes est facilitée si celles-ci sont déclarées dans la classe principale qui les manipule ou qui a un nom très naturel pour deviner que nous la trouverons à l'intérieur.
Par exemple, dans la bibliothèque JDK, les valeurs constantes de l'exponentielle et de pi sont déclarées dans une classe qui déclare non seulement les constantes ( java.lang.Math
).
public final class Math {
...
public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;
...
}
Les clients qui utilisent les fonctions mathématiques s'appuient souvent sur le Math
classe. Ainsi, ils peuvent trouver des constantes assez facilement et peuvent également se souvenir où E
y PI
sont définis de manière très naturelle.
Si votre application ne contient pas une classe existante qui a une cohésion fonctionnelle très spécifique et forte avec les valeurs constantes, les méthodes 1 variante) et 2 variante) semblent plus intuitives.
En général, cela ne facilite pas l'utilisation des constantes si celles-ci sont déclarées dans une classe qui les manipule alors que nous avons aussi 3 ou 4 autres classes qui les manipulent tout autant et aucune de ces classes ne semble plus naturelle que les autres pour accueillir des valeurs constantes.
Dans ce cas, il est judicieux de définir une classe personnalisée pour ne conserver que les valeurs constantes.
Par exemple, dans la bibliothèque JDK, l'élément java.util.concurrent.TimeUnit
L'enum n'est pas déclaré dans une classe spécifique car il n'y a pas vraiment une et une seule classe spécifique au JDK qui apparaît comme la plus intuitive pour le contenir :
public enum TimeUnit {
NANOSECONDS {
.....
},
MICROSECONDS {
.....
},
MILLISECONDS {
.....
},
SECONDS {
.....
},
.....
}
De nombreuses classes déclarées dans java.util.concurrent
les utiliser : BlockingQueue
, ArrayBlockingQueue<E>
, CompletableFuture
, ExecutorService
... et aucun d'entre eux ne semble plus approprié pour contenir l'énumération.
1 votes
Juste pour ajouter constantes java : public/privé
0 votes
Similaire : Partager des chaînes constantes en Java entre plusieurs classes ?