web-dev-qa-db-fra.com

Est-ce une mauvaise pratique d'avoir une interface pour définir des constantes?

J'écris un ensemble de classes de test junit en Java. Il y a plusieurs constantes, par exemple des chaînes dont j'ai besoin dans différentes classes de test. Je pense à une interface qui les définit et chaque classe de test l'implémenterait.

Les avantages que j'y vois sont:

  • accès facile aux constantes: MY_CONSTANT au lieu de ThatClass.MY_CONSTANT
  • chaque constante définie une seule fois

Cette approche est-elle plutôt une bonne ou une mauvaise pratique? J'ai envie de le faire, c'est un peu comme abuser du concept d'interfaces.

Vous pouvez répondre de manière générale sur les interfaces/constantes, mais aussi sur les tests unitaires s'il y a quelque chose de spécial à ce sujet.

45
FabianB

Joshua Bloch le déconseille dans son livre intitulé Java efficace:

Le fait qu'une classe utilise certaines constantes en interne est un détail d'implémentation. L'implémentation d'une interface constante provoque la fuite de ce détail d'implémentation dans l'API exportée des classes. Cela n'a aucune conséquence pour les utilisateurs d'une classe que la classe implémente une interface constante. En fait, cela peut même les confondre. Pire, cela représente un engagement: si dans une future version la classe est modifiée pour ne plus avoir besoin d'utiliser les constantes, elle doit quand même implémenter l'interface pour assurer la compatibilité binaire.

Vous pouvez obtenir le même effet avec une classe normale qui définit les constantes, puis utilisez import static com.example.Constants.*;

88
matt

Dans notre cas, nous le faisons parce que les valeurs des constantes représentent un contrat pour les états finaux qu'une implémentation de service doit fournir. Mettre ces constantes dans l'interface spécifie les états finaux dans le cadre du contrat, et si une implémentation de l'interface ne les utilisait pas, elle ne ferait pas son travail.

Certaines constantes sont des détails d'implémentation. PARFOIS, ils ne le sont pas. Comme d'habitude, un ingénieur doit utiliser son cerveau pour décider quoi faire, et ne pas s'appuyer sur un schéma ou une pratique de balayage.

14
user144901

Je ne pense pas que ce soit une bonne chose d'avoir des interfaces seulement pour les constantes.

Mais si une interface qui définit le comportement (les méthodes implémentant les classes doivent implémenter), a des constantes, c'est OK. S'il "divulgue certains détails de l'implémentateur" dans l'API, c'est parce que c'est ainsi que cela devrait être. Ils fuient également que l'implémenteur implémente les méthodes .foo() et .bar().

Prenons par exemple l'interface Java.awt.Transparency. Il a les constantes OPAQUE, BITMASK et TRANSLUCENT mais a également la méthode .getTransparency().

Si le concepteur y met ces constantes, c'est parce qu'il pensait que ce serait suffisamment stable pour faire partie de l'interface, comme l'est .getTransparency().

6
Tulains Córdova

Une entreprise dans laquelle je travaillais a fait un usage intensif des interfaces importées1 constantes. Je ne sens aucun mal en découler.

La question que vous devriez vous poser est, à quel point l’espace de noms est-il important pour vous? Dans le cas des constantes, c’est vraiment tout ce qu’une classe fait. Si vous avez des milliers de constantes, vous ne voudrez peut-être pas que toutes ces constantes soient toujours disponibles.

Ce qu'il y a de bien avec les interfaces, c'est qu'il vous donne l'avantage de travailler dans les deux sens - apportez tous les espaces de noms dont vous avez besoin, ou aucun d'entre eux (et accédez-y explicitement, avec MyInterface.CONSTANT). À peu près la même chose que import static MyInterface.*, mais un peu plus évident.


1: Si vous n'êtes pas familier avec Java, je ne parle pas du mot clé import, je veux juste dire introduit via implements MyConstantsInterface

2
Nicole

Je pense que c'est un point de vue principalement populaire dans les endroits où la conception par contrat est répandue.
Les interfaces sont des contrats. Placer des constantes dans les interfaces signifie que chaque classe qui respecte le contrat accepte la valeur/le concept identifié par la constante.

2
CMR

Non, ce n'est pas une mauvaise pratique générale.

Le fait est que les constantes comme tout autre artefact devraient être introduites selon les règles de visibilité minimale et de niveau d'abstraction approprié.

Utiliser la syntaxe uniquement parce que vous le pouvez est le vrai problème.

1
oopexpert

Je viens d'un milieu qui est principalement influencé principalement par la "voie Ada" et la "voie .Net". Je dirais non, qu'il n'est probablement pas préférable de déclarer des constantes dans les interfaces. Il n'est techniquement pas autorisé en c #.

La raison pour laquelle je dis non est qu'une interface est une forme de contrat qui définit le comportement, et non un état ou une structure. Une constante implique une sorte d'état (primitif) ou un aspect d'état (composite ou agrégé).

Je peux apprécier l'envie de rendre les valeurs par défaut et les valeurs prédéfinies accessibles à tous ceux qui implémentent l'interface, mais peut-être que l'état par défaut serait mieux décrit dans un objet ou un modèle abstrait ou de valeur, où les valeurs par défaut auraient au moins un contexte minimal.

Pour un guide plus technique: download.Oracle.com/javase/1.5.0/docs/guide/language/static-import.html

1
JustinC