75 votes

Meilleures pratiques pour l'utilisation et la persistance des enums

J'ai vu plusieurs questions/discussions ici sur la meilleure façon de gérer et de faire persister des valeurs de type énumération (par ex. Persistance des données adaptées aux enums , Comment faire persister un enum avec NHibernate ? ), et j'aimerais savoir quel est le consensus général.

En particulier :

  • Comment ces valeurs doivent-elles être traitées dans le code ?
  • Comment les faire persister dans une base de données (en tant que texte/en tant que nombre) ?
  • Quels sont les compromis entre les différentes solutions ?

Note : J'ai déplacé les explications initialement incluses dans cette question vers une réponse.

18voto

Paul Sonier Points 25528

Je suis d'accord avec une grande partie de ce que vous dites. J'aimerais cependant ajouter une chose à propos de la persistance des enums : Je ne pense pas que la génération des enums au moment de la construction à partir des valeurs de la BD soit acceptable, mais je pense aussi que la vérification au moment de l'exécution n'est pas une bonne solution. Je définirais un troisième moyen : avoir un test unitaire qui vérifiera les valeurs de l'enum par rapport à la base de données. Cela permet d'éviter les divergences "occasionnelles" et de ne pas avoir à vérifier les enums par rapport à la base de données à chaque fois que le code est exécuté.

13voto

lokori Points 121

L'article initial me semble correct. Cependant, d'après les commentaires, il semble que quelques commentaires concernant les enums Java pourraient clarifier certaines choses.

Le type Enum en Java est une classe par définition, mais de nombreux programmeurs ont tendance à l'oublier, car ils l'associent plutôt à "une liste de valeurs autorisées" comme dans certains autres langages. C'est bien plus que cela.

Ainsi, pour éviter ces instructions de commutation, il peut être raisonnable de placer du code et des méthodes supplémentaires dans la classe enum. Il n'est presque jamais nécessaire de créer une "classe réelle de type enum" distincte.

Considérez également le point de la documentation - voulez-vous documenter la signification réelle de votre enum dans la base de données ? Dans le code source reflétant les valeurs (votre type d'enum) ou dans une documentation externe ? Personnellement, je préfère le code source.

Si vous souhaitez présenter les valeurs de l'enum sous forme d'entiers dans la base de données pour des raisons de rapidité ou autres, ce mappage doit également résider dans l'enum Java. Par défaut, vous obtiendrez un mappage chaîne-nom, et je m'en suis contenté. Il y a un numéro ordinal associé à chaque valeur de l'enum, mais l'utiliser directement comme mappage entre le code et la base de données n'est pas très intelligent, car ce numéro ordinal changera si quelqu'un réorganise les valeurs dans le code source. Ou ajoute des valeurs d'énumération supplémentaires entre les valeurs existantes. Ou supprime une valeur.

(Bien sûr, si quelqu'un change le nom de l'enum dans le code source, le mappage de la chaîne par défaut devient également aigre, mais il est moins probable que cela se produise accidentellement. Et vous pouvez plus facilement vous protéger contre cela si nécessaire en mettant un contrôle d'exécution et des contraintes de contrôle dans la base de données comme suggéré ici déjà. )

6voto

Quibblesome Points 14441

Dans le traitement du code pour C#, vous avez omis de définir la décompensation de la valeur 0. Je déclare toujours, presque sans faute, ma première valeur comme :

public enum SomeEnum
{
    None = 0,
}

afin de servir de valeur nulle. Parce que le type de support est un entier et qu'un entier a une valeur par défaut de 0, il est donc très utile dans beaucoup d'endroits de savoir si un enum a été programmé ou non.

5voto

David Boike Points 7528

Java ou C# devraient toujours utiliser les enums dans le code. Clause de non-responsabilité : Je suis originaire de C#.

Si la valeur doit être persistée dans une base de données, les valeurs intégrales de chaque membre de l'énumération doivent être explicitement définies afin qu'une modification ultérieure du code n'altère pas accidentellement les valeurs traduites de l'énumération et donc le comportement de l'application.

Les valeurs doivent toujours être persistées dans une base de données en tant que valeurs intégrales, afin de se protéger contre la refactorisation des noms d'enum. Conservez la documentation sur chaque énumération dans un wiki et ajoutez un commentaire au champ de la base de données pointant vers la page wiki documentant le type. Ajoutez également une documentation XML au type d'énumération contenant un lien vers l'entrée wiki afin qu'elle soit disponible via Intellisense.

Si vous utilisez un outil pour générer du code CRUD, il doit être capable de définir un type d'énumération à utiliser pour une colonne afin que les objets du code généré utilisent toujours des membres énumérés.

Si une logique personnalisée doit être appliquée à un membre d'une énumération, vous avez quelques options :

  • Si vous avez un enum MyEnum, créez une classe statique MyEnumInfo qui offre des méthodes utilitaires pour découvrir des informations supplémentaires sur le membre de l'enum, par des instructions de commutation ou tout autre moyen nécessaire. En ajoutant "Info" à la fin du nom de l'énumération dans le nom de la classe, on s'assure qu'ils seront côte à côte dans IntelliSense.
  • Décorez les membres de l'énumération avec des attributs pour spécifier des paramètres supplémentaires. Par exemple, nous avons développé un contrôle EnumDropDown qui crée une liste déroulante ASP.NET remplie de valeurs d'énumération, et un EnumDisplayAttribute spécifie le texte d'affichage joliment formaté à utiliser pour chaque membre.

Je n'ai pas essayé, mais avec SQL Server 2005 ou une version ultérieure, vous pourriez théoriquement enregistrer un code C# avec la base de données qui contiendrait des informations sur les enums et la possibilité de convertir les valeurs en enums pour les utiliser dans des vues ou d'autres constructions, ce qui permettrait de traduire les données d'une manière plus facile à utiliser pour les DBA.

3voto

cjk Points 27463

Le stockage de la valeur textuelle d'une énumération dans une base de données est moins préférable au stockage d'un nombre entier, en raison de l'espace supplémentaire requis et de la recherche plus lente. Elle est précieuse dans la mesure où elle a plus de signification qu'un nombre, mais la base de données sert à stocker et la couche de présentation sert à rendre les choses agréables à regarder.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X