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


40

J'écris un ensemble de classes de test junit en Java. Il existe plusieurs constantes, par exemple des chaînes dont j'aurai 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 je vois sont les suivants:

  • accès facile aux constantes: MY_CONSTANTau lieu deThatClass.MY_CONSTANT
  • chaque constante définie une seule fois

Cette approche est-elle plutôt une bonne ou une mauvaise pratique? J'ai l'impression d'abuser un peu du concept d'interfaces.

Vous pouvez répondre de manière générale aux interfaces / constantes, mais également aux tests unitaires s’il ya quelque chose de spécial.


La réponse pour "C’est une mauvaise pratique d’avoir une interface qui définisse X?", Étant X tout ce qui n’est pas une "signature de méthode", est presque toujours "Oui".
T. Sar - Rétablir Monica

Réponses:


79

Joshua Bloch déconseille cela dans son livre Effective Java :

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 ces détails d'implémentation dans l'API exportée des classes. Pour les utilisateurs d'une classe, le fait que celle-ci implémente une interface constante n'a pas d'importance. En fait, cela peut même les confondre. Pire, cela représente un engagement: si, dans une version ultérieure, la classe est modifiée de manière à ne plus utiliser les constantes, elle doit toujours 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 utiliser import static com.example.Constants.*;


13

Dans notre cas, nous procédons ainsi car les valeurs des constantes représentent un contrat pour les états finaux qu'une implémentation de service doit fournir. La mise de ces constantes dans l'interface spécifie les états finaux dans le 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 modèle ou une pratique générale.


7

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

Mais si une interface qui définit le comportement (les méthodes implémentant des classes doivent l'implémenter), a des constantes, c'est bon. Si "des détails du développeur sont divulgués " dans l'API, c'est que c'est comme ça que ça devrait être. De plus, ils impliquent que l'implémenteur implémente les méthodes foo et bar.

Prenons par exemple l'interface java.awt.Transparency. Il a des constantes OPAQUE, BITMASK et TRANSLUCENT, mais aussi une méthode getTransparency ().

Si le concepteur y met ces constantes, il pense qu'il serait assez stable pour faire partie de l'interface, à l'instar de getTransparency ().


2

Pensez que c'est un point de vue surtout populaire dans les endroits où la conception par contrat prévaut.
Les interfaces sont des contrats. Le fait de placer des constantes dans des interfaces signifie que chaque classe qui respecte le contrat accepte la valeur / le concept identifié par la constante.


1
les interfaces sont des contrats publics. Les VALEURS constantes sont des préoccupations privées, l'interface publique doit tout au plus révéler leurs noms. Cela vaut mieux laisser à une classe abstraite.
Je me suis rendu le

Exemples: javax.naming.Context, javax.ims.Session et des centaines d'interfaces de ce type ...
CMR, le

2
@jwenting En outre, une interface publique pourrait-elle être exposée "at most expose their names"sans exposer les valeurs?
CMR

cela dépend du langage de programmation, je suppose. En cas de Java, non.
Jwenting

2

Une entreprise où je travaillais à fait une utilisation intensive des produits importés d'interface 1 constantes. Je ne ressens aucun mal.

La question que vous devriez vous poser est la suivante: quelle est l’importance de l’espacement des noms pour vous? Dans le cas des constantes, c'est vraiment tout ce qu'une classe agit comme. Si vous avez des milliers de constantes, vous ne voudrez peut-être pas que toutes ces constantes soient toujours disponibles.

La bonne chose à propos des interfaces est que cela vous donne l’avantage de travailler dans un sens ou dans l’autre - introduisez 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 importmot clé, je veux simplement dire introduit viaimplements MyConstantsInterface


1

Je viens d'un milieu principalement influencé par la «méthode Ada» et la «méthode .Net». Je dirais non, qu'il n'est probablement pas préférable de déclarer des constantes dans des interfaces. Ce n'est techniquement pas permis en c #.

La raison pour laquelle je dis non, c'est qu'une interface est une forme de contrat qui définit un 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 comprendre l'envie de mettre les valeurs par défaut et les valeurs prédéfinies à la disposition de 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 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


Ajout de liens faisant référence à l'importation statique (1.5): 1. Wikipedia 2. Oracle Docs faisant référence à @Justinc
Abhijeet

1
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Référence de Oracle Docs
Abhijeet

1

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

Le fait est que les constantes, comme tout autre artefact, doivent ê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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.