É melhor usar strings ou int referenciar enumerações fora da parte java do sistema?

10

Estávamos discutindo no meu trabalho sobre o uso de enums em Java.

Um colega de trabalho estava argumentando que, ao usar enumerações no lado do servidor, sempre que necessário, deveríamos usar string para fazer referência a ela (por exemplo, ao enviar dados de JS para o servidor ou ao armazenar no banco de dados), argumentando que isso é muito mais claro para o desenvolvedor e também argumentando que falharia rapidamente em caso de erros de digitação.

Eu sempre usei números inteiros para identificar enumerações nesses casos, porque seriam identificadores imutáveis ​​e não teriam problemas de maiúsculas e minúsculas (mesmo que um desenvolvedor cometesse o erro de usar o valor 2 em vez de 1, isso não falharia rapidamente).

Sendo muito analítico sobre esses argumentos, eu diria que o uso de strings é melhor, mas tenho uma sensação estranha sobre isso (como se não fosse uma boa abordagem).

Existe alguma prática recomendada em relação a essa discussão que possa me orientar?

Edit: Sempre que possível, usamos o próprio enum, portanto todo o nosso código Java usa o Enum. Por "referência a uma enumeração", quero dizer: referenciar o valor na enumeração ao trocar dados do JavaScript para o servidor ou armazenar dados no banco de dados

JSBach
fonte
11
O que é uma "referência a uma enumeração" para você? Uso normal no código fonte? Serialização para armazenamento em um banco de dados? Expressão para usar na documentação do usuário? Expressão para usar na documentação técnica? A resposta será bem diferente para todos eles.
Kilian Foth
Editei a pergunta e espero que fique mais clara agora: com "referência a uma enum", quero dizer referenciar o valor ao trocar dados de JavaScript para o servidor ou
vice
Na API javascript eu certamente usaria strings. No banco de dados, ambos têm suas vantagens. Alguns bancos de dados criaram suporte enum.
CodesInChaos

Respostas:

15

Boa pergunta. O uso de enum em Java destina-se principalmente a manipular informações de natureza algo categórica. O exemplo clássico é usar enum para lidar com os quatro tipos de naipes que um cartão poderia ter. Ele fornece todas as vantagens de desempenho do uso de um número inteiro e também é claro no seu programa.

Portanto, fora do Java, por que você não continuaria usando um número inteiro? Talvez você não tenha tipos de enumeração fora do Java, embora isso não signifique que você não possa continuar usando o número inteiro para fins de desempenho, certo? Sim, isso é completamente verdade, mas considere o que acontece quando você adiciona um novo valor de enumeração. Se você não adicioná-lo ao final, todos os outros valores de enumeração após o novo valor serão aumentados em um. Bem, apenas especificaremos o número para que ele não possa mudar ou sempre o adicionaremos ao final. Você está confiante de que seus colegas de trabalho sempre farão certo com isso? Meh? Provavelmente? Esperançosamente? Talvez você não esteja 100% nisso. Tenha isso em mente por um segundo.

Seu chefe diz que há uma bagunça no cliente usando seu software após a última atualização. Agora, todas as entidades X agem como se tivessem sido atribuídas a um valor de enumeração Y, mesmo que fossem realmente atribuídas a Z. Você verifica o repositório e, sim, alguém adicionou um novo valor de enumeração e não seguiu suas diretrizes conforme solicitado. Agora você tem a complicação adicional de que no banco de dados está escrito 4, quando realmente deve ser 3, excluindo os registros que foram inseridos antes da atualização que realmente são 4. Qual é o valor da enum para 4, afinal? Não é Y? Você não consegue se lembrar. Você precisa verificar o programa para verificar. Simplificando, é uma bagunça.

Se, em vez disso, seu banco de dados escreveu "HEARTS", "DIAMONDS", "SPADES", "CLUBS", você perdeu pouco em termos de espaço e ganhou muito. É verdade que estamos falando de um pequeno impacto no desempenho, mas você realmente não deve acessar o banco de dados com frequência para fazer a diferença. Quanto ao espaço, deixe isso para os administradores de sistemas (não. Seu. Problema.).

Se você fez um programa simples e fácil de fazer alterações, fez um favor a si mesmo a longo prazo, confie em mim. Este aspecto não é diferente na minha humilde opinião.

Neil
fonte
2
Bons pontos, mas você está esquecendo o caso em que alguém decide alterar o nome de uma das entidades enum ( HEARTSpara Heartou algo no seu exemplo) e, de repente, tudo quebra novamente.
Scott Whitlock
11
@ScottWhitlock Não, se você responder por isso, embora eles possam decidir renomeá-lo completamente. Eles poderiam excluir acidentalmente o banco de dados e também o projeto, mas não podemos contabilizar todos os incidentes possíveis aqui.
Neil
5
@ Neil - verdade, mas estamos tentando jogar as probabilidades aqui. Não estou familiarizado com enumerações Java, mas em C #, defino explicitamente os valores para enumerações, se os valores precisarem ter significado fora do programa (como em um banco de dados) (por exemplo, Copas = 1, Diamantes = 2, etc.) . Como essa não é a maneira padrão de usar uma enumeração, ela deve dar uma pausa posterior ao editor. Além disso, um comentário indicando onde mais eles são usados ​​é útil.
Scott Whitlock
11
@ScottWhitlock Essa é definitivamente a melhor maneira de fazer isso para evitar esses problemas. Embora suponha que você tenha feito isso, você ainda vê 1, 2, 3, 4 no banco de dados ou serializado em algum arquivo. Não é o ideal do ponto de vista de manutenção, da maneira que você o faz.
Neil
2
Se posso acrescentar, se o enum é serializado como string e alguém altera o nome de um enum, durante a desserialização, o erro será durante a análise. Se o enum for int e alguém alterar a definição, o erro será mais abaixo na linha, durante o processamento, o que será mais difícil de diagnosticar. CC @ScottWhitlock.
Endy Tjahjono
1

Concordo com a resposta de Neil, mas apenas uma adição:

Em java enums são objetos, para que eles possam ter campos e métodos. Assim, você pode atribuir a cada enum algum valor especificado manualmente e, quando referenciá-lo para trabalho externo, use esse valor.

Ele sobreviverá ao adicionar / remover / reordenar e alterar o nome da instância enum. Mas você precisará escrever a lógica de serialização / desserialização para campos de enumeração, em vez de usar a automagia disponível em muitas ferramentas. (É fácil, mas é um trabalho adicional).

E você deve manter esses valores exclusivos manualmente (mas isso é o mesmo nas enumerações do estilo C) e pode escrever teste para verificar isso.

user470365
fonte
Sim, seguimos esse caminho, mas estamos usando o hibernate e tivemos que adicionar um código extra para poder analisar o valor de / para o banco de dados e parecia estranho, então decidimos usar o relacionamento .STRING e vá com o nome enum.
JSBach