Entre interfaces et énumérations, lequel est le meilleur pour déclarer des constantes? Pourquoi est-ce le cas?
Les constantes public static final
sont d'une époque antérieure aux enum
. :)
Entre interfaces et énumérations, lequel est le meilleur pour déclarer des constantes? Pourquoi est-ce le cas?
@Bombe, ce n'est pas tout à fait vrai. Si, par exemple, java.lang.Math
devait être réécrit aujourd'hui, PI
et E
seraient toujours déclarés en tant que constantes public static final double
.
Si vos constantes doivent avoir un type spécifique pour une raison, si elles ont besoin d'un certain comportement (c'est-à-dire, des méthodes) ou si ce sont des composites d'autres valeurs, les enum
s sont la solution.
Par exemple, supposons que vous implémentiez un jeu de cartes et que vous vouliez représenter les valeurs et les enseignes :
enum Rank {
ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN,
EIGHT, NINE, TEN, JACK, QUEEN, KING;
}
enum Suit { SPADES, CLUBS, DIAMONDS, HEARTS }
Il est maintenant impossible de créer des cartes avec des enseignes ou des valeurs invalides.
Cependant, parfois, vous êtes juste intéressé par un tas de valeurs fréquemment utilisées déclarées quelque part. Dans ce cas, les mettre dans un enum
serait juste un effort inutile, puisque ces constantes ne sont qu'un outil pour nous éviter de mémoriser tous les décimales de, disons, π lorsque nous calculons la circonférence d'un cercle, ou quelque chose. Qu'est ce qui est mieux ?
// Utilisation de enum:
enum MathConstant {
PI(3.14159265358979323846), E(2.7182818284590452354);
private final double value;
MathConstant(double v) { value = v; }
public double value() { return value; }
}
// Usage:
double circonférence = MathConstant.PI.value() * diamètre;
// Utilisation d'une classe constante:
final class MathConstants {
private MathConstants() { throw new UnsupportedOperationException(); }
public static final double PI = 3.14159265358979323846,
E = 2.7182818284590452354;
}
// Usage:
double circonférence = MathConstants.PI * diamètre;
Pour ce qui est des interfaces : Ne mettez jamais de constantes dans une interface. Le pattern "interface constante" est mauvais (justification), et le seul argument pour l'utiliser a été rendu caduc depuis l'ajout de import static
à Java.
L'interface publique HttpStatus d'Apache place des constantes dans une interface, ce que vous avez conseillé de ne pas faire. Par exemple - int SC_OK = 200; Les classes peuvent utiliser ces constantes en important statiquement HttpStatus. Est-ce que l'utilisation de l'interface ici pose toujours problème ?
Eh bien, en quelque sorte. La principale raison contre les interfaces avec des constantes est que cela rend facile et confortable d'implémenter
l'interface juste pour éviter d'avoir à importer les constantes. Il y a aussi des raisons sémantiques contre cela ; une interface est un ensemble de comportements qui peuvent être implémentés, pas un sac de constantes. Maintenant, les classes ne sont pas vraiment des endroits sémantiquement corrects pour placer des constantes non plus, mais elles peuvent être rendues finales et non instanciables, ce qui les fait se comporter davantage comme des sous-espaces de noms plutôt que des classes (ce que nous voulons).
Les interfaces sont conçues pour définir des comportements communs, les enums pour définir des valeurs communes.
L'enum représente une valeur réelle qui peut être comparée à une autre valeur, ou stockée dans la base de données facilement. Vous pouvez également avoir un drapeau-enum (en C#, je ne sais pas en Java) qui vous permet d'effectuer des opérations binaires sur les valeurs de l'enum (ET, OU, XOR, etc).
En Java, les énumérations sont essentiellement des classes (constants), ainsi vous pouvez faire beaucoup plus avec eux qu'avec les énumérations en c# avant .net 4.0. Je pense que C# / .net 4.0 va implémenter cette fonctionnalité.
Si vous travaillez avec Java 5 ou une version plus récente, alors les Enum sont la voie à suivre. La seule exception est si votre liste de const est ouverte et peut être étendue. Les énumérations ne peuvent pas être étendues. Une autre exception est si ce sont des valeurs uniques comme un MAX_INTEGER.
Juste un code :
public interface InterfaceForConstants() {
String **TOTO** = "Et voilà !";
double **PI** = 3.14159265358979323846;
}
En utilisant :
class ClasseName implements InterfaceForConstants () {
String myString;
if (myString.equals(**TOTO**) {
// faire quelque chose
}
double circonférence = **PI** * diamètre; // au lieu de MathConstants.PI * diamètre;
}
Propre et simple. Si quelque chose peut faire ce dont vous avez besoin, prenez la solution la plus simple ! Écrire du code selon les règles est bien, écrire du code facile à lire est mieux, même si une règle n'est pas respectée. Pensez à quand vous devrez relire votre code après quelques mois. Si vous voulez être plus précis, faites une javadoc pour l'expliquer !
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.