Antipattern Java : Interface de constantes
Publié le 16 Janvier 2013
Voilà un pattern que je rencontre dans notre codebase actuel. Il s'agit d'utiliser une interface java pour y définir des constantes.
Par exemple:
public interface Constantes {
public static final String MY_NAME = "my_name";
// etc ...
}
Ensuite la classe qui utilise ces constantes implémente l'interface:
public class MaClasse implements Constantes {
private String name = MY_NAME;
// etc ...
}
En implémentant l'interface Constantes on peut utiliser directement le nom des constantes sans les préfixer par le nom de l'interface. C'est vrai ça fait plus clair dans le code car on gagne en lisibilité.
Cependant il y a quelques inconvénients qui peuvent faire perdre un temps fou en support (en débuggage quoi).
En fait les constantes sont héritées de l'interface (oui ça fait bizarre pour des champs static mais c'est bien le cas).
De plus si je déclare une constante MY_NAME dans MaClasse je vais masquer celle de l'interface:
public class MaClasse implements Constantes {
private static final String MY_NAME = "ma_classe";
private String name = MY_NAME;
// etc ...
}
Maintenant name vaut "ma_classe" et non plus "my_name" comme défini dans l'interface.
Encore ici on a un lien direct avec l'interface mais ça peut être moins évident avec des sous-classes qui n'implémente pas l'interface directement. (Normalement l'IDE génère un warning en cas de masquage, mais bon).
En fait il existe un moyen plus sûr de faire la même chose. Au lieu d'utiliser une interface il faut mieux utiliser une classe non instanciable, puis utiliser un import static dans la classe qui utilise ces constantes:
public final class Constantes {
private Constantes(){
throw new UnsupportedOperationException();
}
public static final String MY_NAME = "my_name";
// etc ...
}
Ensuite dans la classe qui utilise les constantes:
import static mon.package.Constantes.*;
public class MaClass {
private String name = MY_NAME;
// etc ...
}
On garde la même lisibilité qu'avec l'interface et les constantes ne sont plus héritées ce qui évite le risque de confusion.