¿Es mejor usar cadenas o int para hacer referencia a enumeraciones fuera de la parte de Java del sistema?

11

Estábamos discutiendo en mi trabajo sobre el uso de enumeraciones en Java.

Un compañero de trabajo argumentaba que cuando se usan enumeraciones en el lado del servidor, siempre que sea necesario, debemos usar cadenas para hacer referencia a él (por ejemplo, al enviar datos desde JS al servidor o al almacenar en la base de datos), argumentando que esto es mucho más claro para el desarrollador y también argumentando que fallaría rápidamente en caso de errores tipográficos.

Siempre usé números enteros para identificar enumeraciones en estos casos, porque serían identificadores inmutables y no tendrían problemas de mayúsculas y minúsculas (aunque un desarrollador cometiera el error de usar el valor 2 en lugar de 1, no fallaría rápidamente).

Siendo muy analítico sobre estos argumentos, diría que usar cadenas es mejor, pero me da una sensación extraña (como si no fuera un buen enfoque).

¿Hay alguna mejor práctica con respecto a esta discusión que pueda guiarme?

Editar: siempre que sea posible, utilizamos la enumeración en sí, por lo que todo nuestro código Java utiliza la enumeración. Por "referencia a una enumeración" quiero decir: hacer referencia al valor en la enumeración al intercambiar datos de JavaScript al servidor o almacenar datos en la base de datos

JSBach
fuente
1
¿Qué es para usted una "referencia a una enumeración"? Uso normal dentro del código fuente? ¿Serialización para almacenar en una base de datos? ¿Expresión para usar en la documentación del usuario? ¿Expresión para usar en documentación técnica? La respuesta será bastante diferente para todos esos.
Kilian Foth
He editado la pregunta y espero que ahora sea más clara: por "referencia a una enumeración" me refiero a hacer referencia al valor al intercambiar datos de JavaScript al Servidor o al revés o almacenar un valor en la base de datos
JSBach
En la API de JavaScript, ciertamente usaría cadenas. En el DB ambos tienen sus ventajas. Algunas bases de datos han incorporado soporte de enumeración.
CodesInChaos

Respuestas:

15

Buena pregunta. El uso de enum en Java está destinado principalmente a manejar información que es de naturaleza categórica. El ejemplo clásico es usar enum para manejar los cuatro tipos de palos que podría tener una tarjeta. Proporciona todas las ventajas de rendimiento del uso de un número entero y también está claro en su programa.

Entonces, fuera de Java, ¿por qué no seguirías usando un número entero? Tal vez no tenga tipos de enumeración fuera de Java, aunque eso no significa que no pueda continuar usando enteros con fines de rendimiento, ¿verdad? Sí, eso es completamente cierto, aunque considere lo que sucede cuando agrega un nuevo valor de enumeración. Si no lo agrega al final, todos los demás valores de enumeración después del nuevo valor se incrementarán en uno. Bueno, solo especificaremos el número para que no pueda cambiar o siempre lo agregaremos al final. ¿Confía en que sus compañeros de trabajo siempre harán lo correcto? Meh ¿Probablemente? ¿Ojalá? Tal vez no estás 100% en eso. Tenlo en cuenta por un segundo.

Su jefe le dice que hay un desastre en el cliente que usa su software después de la última actualización. Ahora todas las entidades X actúan como si se les asignara un valor de enumeración Y, incluso si realmente se les asignó Z. Usted verifica el repositorio y sí, alguien agregó un nuevo valor de enumeración y no siguió sus pautas como se lo pidió. Ahora tiene la complicación adicional de que en la base de datos está escrito 4, cuando realmente debería ser 3, excluyendo los registros que se han insertado antes de la actualización que realmente son 4. ¿Qué valor de enumeración corresponde a 4 de todos modos? ¿No es Y? No te acuerdas. Debe verificar el programa para verificar. En pocas palabras, es un desastre.

Si, en cambio, su base de datos escribió "CORAZONES", "DIAMANTES", "ESPADAS", "CLUBES", ha perdido poco en términos de espacio y ha ganado mucho. Es cierto que estamos hablando de un impacto menor en el rendimiento, pero realmente no debería estar accediendo a la base de datos con tanta frecuencia para marcar la diferencia. En cuanto al espacio, déjelo a los administradores de sistemas (no. Su. Problema.).

Si ha hecho un programa simple al que es fácil hacer cambios, se ha hecho un favor a largo plazo, confíe en mí. Este aspecto no es diferente en mi humilde opinión.

Neil
fuente
2
Los buenos puntos, pero estás olvidando el caso en que alguien decide cambiar el nombre de una de las entidades de enumeración ( HEARTSa Hearto algo en su ejemplo) y de repente todo se rompe de nuevo.
Scott Whitlock
1
@ScottWhitlock No, si lo explicas, aunque podrían decidir cambiarle el nombre por completo. Podrían eliminar accidentalmente la base de datos y eliminar el proyecto también, pero no podemos dar cuenta de todos los posibles incidentes aquí.
Neil
55
@Neil: cierto, pero estamos tratando de jugar las probabilidades aquí. No estoy familiarizado con las enumeraciones de Java, pero en C #, configuro explícitamente los valores para enumeraciones si los valores necesitan tener un significado fuera del programa (como en una base de datos) (por ejemplo, Corazones = 1, Diamantes = 2, etc.) . Como esa no es la forma predeterminada de usar una enumeración, debería dar una pausa posterior al editor. Además, es útil un comentario que indique dónde más se usan.
Scott Whitlock
1
@ScottWhitlock Esa es definitivamente la mejor manera de hacerlo para evitar tales problemas. Aunque suponiendo que hiciste eso, todavía ves 1, 2, 3, 4 en la base de datos o serializados en algún archivo. No es ideal desde el punto de vista del mantenimiento de ninguna manera.
Neil
2
Si puedo agregar, si la enumeración se serializa como una cadena y alguien cambia el nombre de una enumeración, durante la deserialización, el error será durante el análisis. Si la enumeración es int y alguien cambia la definición, el error estará más adelante, durante el procesamiento, lo que será más difícil de diagnosticar. CC @ScottWhitlock.
Endy Tjahjono
1

Estoy de acuerdo con la respuesta de Neil, pero solo una adición:

En Java las enumeraciones son objetos, por lo que pueden tener campos y métodos. Por lo tanto, puede dar a cada enumeración un valor especificado manualmente y, al hacer referencia al trabajo externo, use ese valor en su lugar.

Sobrevivirá tanto agregando / eliminando / reordenando como cambiando el nombre de la instancia de enum. Pero tendrá que escribir la lógica de serialización / deserialización para los campos de enumeración en lugar de utilizar el autómata disponible en muchas herramientas. (Es fácil, pero es un trabajo adicional).

Y debe mantener esos valores únicos manualmente (pero eso es lo mismo en las enumeraciones de estilo C), y puede escribir una prueba para verificar eso.

user470365
fuente
Sí, seguimos este camino, pero estamos usando hibernate y tuvimos que agregar un código adicional para poder analizar el valor hacia / desde la base de datos y parecía un poco extraño, así que decidimos usar la relación .STRING y ir con el nombre de enumeración.
JSBach