Les meilleures pratiques pour l'utilisation et la persistance des enums
J'ai vu plusieurs questions/débats sur la meilleure façon de gérer et de persister enum-comme valeurs (par exemple,La persistance de données adapté pour les enums , Comment faire pour conserver un enum à l'aide de NHibernate ), et j'aimerais demander à ce que le général consenus est.
En particulier:
- Comment ces valeurs seront traitées dans le code?
- Comment doivent-elles être conservées dans une base de données (en tant que texte/comme un certain nombre)?
- Quels sont les avantages et les inconvénients des différentes solutions?
Remarque: j'ai déplacé les explications à l'origine inclus dans cette question, d'une réponse.
Vous devez vous connecter pour publier un commentaire.
Je suis d'accord avec beaucoup de ce que vous dites. Une chose que je voudrais ajouter, cependant, la persistance d'énumérations: je ne crois pas que la génération de l'option au moment de la construction de la DB valeurs est acceptable, mais je pense aussi que le moment de l'exécution n'est pas une bonne solution. J'avais définir un troisième moyen: disposer d'une unité de test qui permettra de vérifier les valeurs de l'enum sur la base de données. Cela empêche les "casual" de la divergence, et évite la surcharge de vérifier les énumérations à l'encontre de la base de données chaque fois que le code est exécuté.
L'article initial semble bien pour moi. Toujours sur la base des commentaires, il semble que certains commentaires concernant Java enums, pour préciser quelques petites choses.
Type Enum en Java, une classe, par définition, mais de nombreux programmeurs ont tendance à l'oublier, parce qu'ils correspondent plutôt à "une liste de valeurs autorisées", comme dans quelques autres langues. C'est plus que cela.
Donc, pour éviter ces instructions de commutation, il pourrait être raisonnable de mettre un peu de code et d'autres méthodes dans la classe enum. Il n'y a presque jamais besoin de créer un "enum-comme une vraie classe".
Considérer également le point de la documentation - voulez-vous de document de la signification réelle de votre enum dans la base de données? Dans le code source en reflétant les valeurs (votre type enum) ou, dans certains documentation externe? Personnellement, je préfère le code source.
Si vous voulez présenter les valeurs de l'enum comme des entiers dans la base de données en raison de la vitesse ou quelle que soit la raison, que la cartographie doit également résider dans l'enum de Java. Vous obtiendrez string-nom de mappage par défaut, et j'ai été satisfait. Il y a un numéro de série associés à chaque valeur d'enum, mais en utilisant directement une correspondance entre le code et la base de données n'est pas très clair, parce que le nombre ordinal va changer, si quelqu'un réorganise les valeurs dans le code source. Ou ajoute les valeurs de l'enum entre les valeurs existantes. Ou supprime une partie de la valeur.
(Bien sûr, si quelqu'un modifie le nom de l'enum dans le code source, la valeur par défaut de la chaîne de cartographie va sure, mais c'est moins susceptible de se produire accidentellement. Et vous pouvez plus facilement protéger contre que, si nécessaire, en mettant certains d'exécution-contrôle et de la vérification des contraintes dans la base de données comme suggéré ici déjà. )
Dans le traitement du code en C# vous avez raté la définition delcaring la valeur 0.
J'ai presque sans faute toujours déclarer ma première valeur:
De manière à servir comme une valeur null. Parce que le type de dossier est un entier et un entier qui vaut 0 par défaut de sorte qu'il est très utile dans beaucoup d'endroits de savoir si un enum a en fait été par programmation définie ou pas.
J'ai essayé de résumer ma compréhension. N'hésitez pas à modifier si vous avez des corrections. Donc, ici, il va:
Dans le code
Dans le code, les énumérations doivent être manipulés à l'aide de la langue maternelle de type enum (au moins en Java et C#), ou d'utiliser quelque chose comme le "typesafe enum modèle". À l'aide de la plaine des constantes (Entier ou similaire) n'est pas recommandée, car vous perdez de sécurité de type (et il est difficile de comprendre les valeurs qui sont les éléments juridiques pour par exemple une méthode).
Le choix entre les deux dépend de la façon dont beaucoup de fonctionnalités supplémentaires, est jointe à l'enum:
En particulier, au moins en Java un enum ne peut pas hériter d'une autre classe, donc si vous avez plusieurs énumérations avec un comportement similaire qui vous voulez mettre dans une super-classe, vous ne pouvez pas utiliser Java enums.
La persistance des enums
Persister enums, chaque valeur d'enum doit être attribué un ID unique. Ce peut être un entier ou une chaîne courte. Une courte chaîne est préféré, car il peut être mnémonique (il est plus facile pour les Administrateurs de base de données etc. pour comprendre les données brutes dans la db).
Un problème avec cette approche est que la liste de ces valeurs enum existe en deux endroits (code et la base de données). C'est difficile à éviter, et donc souvent considéré comme acceptable, mais il y a deux alternatives:
Java ou C# doit toujours utiliser les énumérations dans le code. Avertissement: Mon expérience est C#.
Si la valeur est conservée dans une base de données, l'intégrale des valeurs de chaque membre de l'énumération doit être explicitement définie, de sorte que plus tard, changement de code n'est pas accidentellement modifier traduit les valeurs de l'enum et donc le comportement de l'application.
Valeurs doivent toujours être conservées dans une base de données en tant que partie intégrante des valeurs, pour se protéger contre enum nom de refactoring. Conserver la documentation sur chaque énumération dans un wiki et ajoutez un commentaire pour le champ de base de données pointant vers la page wiki de documenter le type. Également ajouter de la documentation XML de type enum contenant un lien vers le wiki entrée de sorte qu'il est disponible par le biais de la fonctionnalité Intellisense.
Si vous utilisez un outil pour générer des CRUD code, il devrait être capable de définir un type d'énumération à utiliser pour une colonne, de sorte que le code généré des objets, utilisez toujours des membres énumérés.
Si la logique personnalisée doit être appliquée pour un membre d'énumération, vous avez quelques options:
Je n'ai pas essayé, mais avec SQL Server 2005 ou plus tard, vous pourriez théoriquement registre de code C# avec la base de données qui contiendrait enum de l'information et de la capacité de convertir les valeurs pour les énumérations, pour une utilisation dans les vues ou d'autres constructions, de faire une méthode pour traduire les données d'une manière plus facile pour les Administrateurs de base de données à utiliser.
Stocker la valeur de texte d'un enum dans une base de données est moins privilégiées pour stocker un entier, en raison de l'espace supplémentaire requis et le ralentissement de la recherche. Il est précieux en ce qu'il a plus de sens qu'un certain nombre, cependant, la base de données pour le stockage et la couche de présentation est pour faire des choses agréables à regarder.
Bien, de mon expérience, en utilisant les énumérations pour autre chose que de passer des options (comme les drapeaux) immédiatement un appel de méthode, les résultats en
switch
-ing à un certain point.switch
déclaration)switch
-es dans vos méthodes d'extension si pas ailleurs.Donc pour un enum-comme entité avec un peu plus de fonctionnalités que vous devez prendre un certain temps et créer une classe, avec plusieurs choses à l'esprit:
Chaque fois que vous trouvez votre auto à l'aide de "nombres magiques" dans le code de changement pour les énumérations. Outre le gain de temps ( depuis la magie disparaîtra lorsque les bugs venir...), il permettra d'économiser vos yeux et la mémoire (significatif énumérations de rendre le code plus lisible et l'auto-documentation), car devinez quoi - vous êtes probablement à la personne de maintenir et de développer votre propre code
À mon humble avis, que pour la partie code:
Vous devriez toujours utiliser le 'enum' type pour votre énumérations, fondamentalement, vous obtenez beaucoup de cadeaux si vous n': Type de sécurité, d'encapsulation et de basculer de l'évitement, de l'appui de certaines collections comme
EnumSet
etEnumMap
et le code de la clarté.comme pour la persistance de la partie, vous pouvez toujours persister la représentation de chaîne de l'enum et la charge à l'aide de l'enum.valueOf(String) de la méthode.
Je sais que c'est un vieux forum, que si la base de données peut avoir d'autres choses intégrant directement à elle? E. g. lorsque la DB est le SEUL but de ce code. Ensuite, vous serez en définissant les énumérations à chaque intégration. Mieux que de les avoir dans la DB. Sinon, je suis d'accord avec le post original.