Est-il préférable d'utiliser des chaînes ou int pour référencer des énumérations en dehors de la partie java du système?

11

Nous avons eu une discussion à mon travail sur l'utilisation des énumérations en Java.

Un collègue faisait valoir que lors de l'utilisation d'énumérations côté serveur, chaque fois que cela était nécessaire, nous devions utiliser une chaîne pour y faire référence (par exemple lors de l'envoi de données de JS au serveur ou lors du stockage dans la base de données), faisant valoir que cela était beaucoup plus clair. pour le développeur et arguant également qu'il échouerait rapidement en cas de fautes de frappe.

J'ai toujours utilisé des entiers pour identifier les énumérations dans ces cas, car ce seraient des identificateurs immuables et n'auraient pas de problèmes de casse et de faute de frappe (même si un développeur commettait l'erreur d'utiliser la valeur 2 au lieu de 1, cela n'échouerait pas rapidement).

Étant très analytique sur ces arguments, je dirais qu'il est préférable d'utiliser des chaînes, mais j'ai un sentiment étrange à ce sujet (comme si ce n'était pas une bonne approche).

Y a-t-il une meilleure pratique concernant cette discussion qui pourrait me guider?

Edit: Chaque fois que cela est possible, nous utilisons l'énumération elle-même, donc tout notre code Java utilise l'énumération. Par "référence à une énumération", j'entends: référencer la valeur de l'énumération lors de l'échange de données de JavaScript vers le serveur ou du stockage de données dans la base de données

JSBach
la source
1
Qu'est-ce qu'une "référence à une énumération" pour vous? Utilisation normale dans le code source? Sérialisation pour le stockage dans une base de données? Expression à utiliser dans la documentation utilisateur? Expression à utiliser dans la documentation technique? La réponse sera tout à fait différente pour tous ceux-là.
Kilian Foth
J'ai édité la question et j'espère qu'elle est plus claire maintenant: par "référence à une énumération", je veux dire référencer la valeur lors de l'échange de données de JavaScript vers le serveur ou l'inverse ou stocker une valeur dans la base de données
JSBach
Dans l'API javascript, j'utiliserais certainement des chaînes. Dans la DB, les deux ont leurs avantages. Certaines bases de données ont un support enum intégré.
CodesInChaos

Réponses:

15

Bonne question. L'utilisation d'énumération en Java est principalement destinée à gérer des informations de nature quelque peu catégorique. L'exemple classique étant d'utiliser l'énumération pour gérer les quatre types de combinaisons qu'une carte pourrait avoir. Il offre tous les avantages de performance de l'utilisation d'un entier et il est également clair dans votre programme.

En dehors de Java, pourquoi ne continueriez-vous pas à utiliser un entier? Peut-être que vous n'avez pas de types d'énumération en dehors de Java, bien que cela ne signifie pas que vous ne pouvez pas continuer à utiliser l'entier à des fins de performances, non? Oui, c'est tout à fait vrai, mais réfléchissez à ce qui se passe lorsque vous ajoutez une nouvelle valeur d'énumération. Si vous ne l'ajoutez pas à la fin, toutes les autres valeurs d'énumération après la nouvelle valeur seront augmentées d'une unité. Eh bien, nous allons simplement spécifier le nombre afin qu'il ne puisse pas changer ou nous l'ajouterons toujours à la fin. Êtes-vous confiant que vos collègues de travail feront toujours bien? Meh? Probablement? J'espère? Peut-être que vous n'êtes pas à 100% là-dessus. Gardez cela à l'esprit pendant une seconde.

Votre patron vous dit qu'il y a un problème avec le client qui utilise votre logiciel après la dernière mise à jour. Maintenant, toutes les entités X agissent comme si la valeur d'énumération Y leur avait été affectée, même si elles étaient vraiment affectées Z. Vous vérifiez le référentiel et oui, quelqu'un a ajouté une nouvelle valeur d'énumération et n'a pas suivi vos directives comme vous l'avez demandé. Maintenant, vous avez la complication supplémentaire que sur la base de données, il est écrit 4, alors qu'il devrait vraiment être 3, à l' exclusion des enregistrements qui ont été insérés avant la mise à jour qui sont vraiment 4. Quelle valeur d'énumération se rapporte à 4 de toute façon? N'est-ce pas Y? Tu ne te souviens pas. Vous devez vérifier le programme pour vérifier. Autrement dit, c'est un gâchis.

Si, au lieu de cela, votre base de données écrivait "COEURS", "DIAMANTS", "SPADES", "CLUBS", vous avez peu perdu en termes d'espace et gagné tellement. Il est vrai que nous parlons d'un impact mineur sur les performances, mais vous ne devriez vraiment pas accéder à la base de données souvent pour faire la différence. Quant à l'espace, laissez cela aux administrateurs système (pas. Votre. Problème.).

Si vous avez créé un programme simple et facile à modifier, vous vous êtes rendu service à long terme, croyez-moi. Cet aspect n'est pas différent à mon humble avis.

Neil
la source
2
De bons points, mais vous oubliez le cas où quelqu'un décide de changer le nom de l'une des entités d'énumération ( HEARTSen Heartou quelque chose dans votre exemple) et soudain, tout se brise à nouveau.
Scott Whitlock
1
@ScottWhitlock Pas si vous en tenez compte, bien qu'ils puissent décider de le renommer entièrement. Ils pourraient accidentellement supprimer la base de données et supprimer le projet également, mais nous ne pouvons pas prendre en compte tous les incidents possibles ici.
Neil
5
@Neil - vrai mais nous essayons de jouer les cotes ici. Je ne connais pas les énumérations Java, mais en C #, je définis explicitement les valeurs pour les énumérations si les valeurs doivent avoir un sens en dehors du programme (comme dans une base de données) (par exemple Hearts = 1, Diamonds = 2, etc.) . Comme ce n'est pas la façon par défaut d'utiliser une énumération, cela devrait donner une pause à l'éditeur plus tard. De plus, un commentaire indiquant où ils sont utilisés est pratique.
Scott Whitlock
1
@ScottWhitlock C'est certainement la meilleure façon de procéder pour éviter de tels problèmes. En supposant que vous ayez fait cela, vous voyez toujours 1, 2, 3, 4 sur la base de données ou sérialisés dans un fichier. Pas idéal du point de vue de la maintenance de quelque façon que ce soit.
Neil
2
Si je peux ajouter, si l'énumération est sérialisée en chaîne et que quelqu'un change le nom d'une énumération, pendant la désérialisation, l'erreur se produira pendant l'analyse. Si l'énumération est int et que quelqu'un modifie la définition, l'erreur sera plus loin sur la ligne, pendant le traitement, ce qui sera plus difficile à diagnostiquer. CC @ScottWhitlock.
Endy Tjahjono
1

Je suis d'accord avec la réponse de Neil, mais juste un ajout:

En java, les énumérations sont des objets, donc elles peuvent avoir des champs et des méthodes. Vous pouvez donc donner à chaque énumération une valeur spécifiée manuellement et lorsque vous la référencez pour un travail extérieur, utilisez plutôt cette valeur.

Il survivra à la fois à l'ajout / la suppression / la réorganisation et au changement du nom de l'instance d'énumération. Mais vous devrez écrire une logique de sérialisation / désérialisation pour les champs enum au lieu d'utiliser automagic disponible dans de nombreux outils. (C'est facile, mais son travail supplémentaire).

Et vous devez conserver ces valeurs uniques manuellement (mais c'est la même chose dans les énumérations de style C), et vous pouvez écrire un test pour le vérifier.

user470365
la source
Oui, nous avons suivi ce chemin, mais nous utilisons hibernate et nous avons dû ajouter du code supplémentaire pour pouvoir analyser la valeur vers / depuis la base de données et cela semblait assez étrange, nous avons donc décidé d'utiliser la relation .STRING et aller avec le nom enum.
JSBach