É um título muito vago, mas não consegui pensar em uma maneira melhor de expressá-lo. Mas, apenas como exemplo, pense na direção em que um personagem de um jogo está se movendo. Parece meio errado usar uma corda e depois fazer coisas como if(character.direction == "left")
. Parece-me que deixa muito espaço para erros tolos, como usar acidentalmente Left
ou o que l
quer que seja left
. Minhas suspeitas estão corretas? Em caso afirmativo, qual é a maneira preferida de conseguir algo assim?
19
bash
,.Respostas:
Se o idioma que você está usando suporta o uso de enumerações, eu os usaria. Permite limitar o número de opções disponíveis para um determinado tipo. por exemplo, em Java:
fonte
enum
como java. Muitos idiomas (por exemplo, VBA) possuemenum
, mas pode não ser a melhor opção, pois não possui a mesma prova de futuro. Veja minha resposta para uma discussão sobre por queenum
apenas uma solução incompleta, geralmente quebradiça e específica de idioma.É uma prática terrível usar cadeias literais (ou números mágicos) no código.
As enumerações são boas ou, pelo menos, usam constantes (as enumerações são apenas um tipo de invólucro para uma ou mais constantes relacionadas).
Essa mudança simples tem tantas vantagens que eu nem saberia por onde começar a explicá-las (pelo menos não sem mais café). Leia sobre números mágicos, é o mesmo conceito exato, aplicado apenas a um valor numérico em vez de um valor de string.
Aqui está uma referência rápida, tenho certeza que há centenas mais: /programming/47882/what-is-a-magic-number-and-why-is-it-bad
fonte
Resposta curta: Sim, as strings não são ideais para nenhuma tarefa além de armazenar e acessar uma sequência de caracteres textuais e, mesmo que os bits subjacentes de uma abstração sejam strings, há benefícios em referenciá-los como variáveis ou constantes .
Resposta longa: a maioria dos idiomas oferece tipos que estão mais próximos do domínio do seu problema e, mesmo que não, eles provavelmente possuem algum método pelo qual você pode definir
left
como uma entidade diferente deright
(etc etc). Transformar isso em uma string usando"left"
é simplesmente perda da linguagem e da funcionalidade útil do IDE, como verificação de erro. Mesmo se você precisar usarou algo equivalente, ele tem vantagens em usar a string quando você se refere a ela em seu código. Por exemplo,
seria detectado como um erro em tempo de compilação (na melhor das hipóteses, java e outros) ou seria sinalizado por qualquer IDE que tivesse seus bits como errado (na pior das hipóteses, básico e tal).
Além disso, ter a noção de
left
uma entidade referenciável o ajudará a acomodar qualquer direção que você decidir seguir com o tipo de direção. Ao usar"left"
, a direção está comprometida em ser aString
. Se você encontrar ou criar uma abstração melhor para o tipo, precisará procurar por todo o corpo do código, alterando cada instância de"left"
. Uma constante ou variável não exigirá nenhuma alteração se o tipo for elaborado.O tipo que você realmente deseja é específico para o seu domínio. O que seu código está planejando fazer com o seu
left
? Talvez você queira espelhar o eixo x de uma textura ou sprite que esteja voltado para a esquerda ou avance;left
Nesse caso, convém criar um objeto com uma propriedade ou método que reflita esse comportamento, com oright
objeto tendo o resultado não espelhado oposto. Você pode fazer essa lógica em um objeto que representa os sprites ou texturas; nesse caso, novamente, você sofrerá o uso, em"left"
vez deleft
pelos motivos mencionados acima.Em Java (e provavelmente em outras linguagens que ainda não conheço),
enum
é uma boa alternativa porque, em Java,enum
é tão útil quantofinal class
em um conjunto finito de instâncias. Você pode definir comportamentos, se precisar deles, e pode mudar para uma classe aberta sem aborrecimentos fora do arquivo que declara oenum
, mas muitos idiomas vêem issoenum
como um tipo primitivo ou requerem sintaxe especial para usar. Isso vaza oenum
código para o código que não tem nada a ver com ele e pode precisar ser corrigido posteriormente. Certifique-se de entender o conceito de um idiomaenum
antes de considerar a opção.fonte
Você não especificou seu idioma, mas, para fornecer uma resposta genérica, use cadeias de caracteres quando realmente precisar do texto, para não representar algo. O exemplo que você deu, por exemplo, simplesmente não seria aceitável no software de produção.
Cada idioma possui vários tipos de dados básicos e você deve usar o mais apropriado para a tarefa. Para usar seu exemplo, você pode usar constantes numéricas para representar estados diferentes. Portanto, a esquerda poderia ter um valor zero e a direita seria um. Além do motivo mencionado, os valores numéricos ocupam menos espaço (memória) e é sempre mais rápido comparar números do que comparar várias seqüências de caracteres.
Como foi sugerido, use enumerações se o seu idioma permitir. No seu exemplo específico, é claramente a melhor escolha.
fonte
if (uppercase(foo) == "LEFT")
Basta usar o tipo de dados que faz sentido na sua situação.
O uso do
string
tipo como uma comunicação inter / intra-aplicativo subjacente não é inerentemente um problema. De fato, às vezes é preferível usar strings: se você tem uma API pública, pode ser desejável que os valores que entram e saem da API sejam legíveis por humanos. Isso facilita para as pessoas que usam sua API aprender e depurar.O verdadeiro problema com o seu código está na repetição do valor.
Não faça isso:
Se você digitou um erro de digitação em um desses condicionais ou em outros usos de "esquerda" em algum lugar, talvez não seja possível executar efetivamente uma pesquisa em toda a base de código, porque você digitou errado!
Em vez disso, codifique contra uma enumeração ou uma constante - dependendo do suporte ao tipo de dados necessário no (s) idioma (s) que você está usando.
Esse meio
LEFT
deve ser atribuído uma vez e apenas uma vez em seu aplicativo. E o restante do seu código deve aproveitar essas enumerações ou constantes:Isso também permite que você altere mais facilmente o tipo de dados que você usa para suas direções posteriormente, se assim o desejar.
fonte
É uma prática ruim?
Provavelmente sim, mas isso depende exatamente do que você está fazendo e também da linguagem de programação que você está usando.
No seu exemplo, podemos inferir que existe um conjunto pequeno e fixo de valores para sempre que uma direção pode tomar. Nesse caso, não há vantagens no uso de uma string e algumas desvantagens definidas. Para este exemplo:
enum
tipo seria preferível, se sua linguagem de programação suportar isso.Mas a resposta pode ser diferente se o conjunto de valores for dinamicamente modificável ou precisar evoluir ao longo do tempo. Na maioria dos idiomas, alterar um
enum
tipo (por exemplo, para adicionar ou remover um valor) requer uma recompilação completa. (Por exemplo, a remoção de um valor de enum em Java quebra a compatibilidade binária.) E o mesmo se aplica às constantes inteiras nomeadas.Em cenários como esse, outra solução pode ser necessária e o uso de strings é uma das opções. (E você pode combinar literais de seqüência de caracteres e constantes nomeadas ... se o cenário envolver um núcleo fixo com extensões dinâmicas.)
Se você estiver implementando em Java,
character.direction == "left"
é uma prática ruim por outro motivo. Você não deve usar==
para comparar cadeias, porque está testando identidades de objetos em vez de igualdade de cadeias. (Funcionaria se você pudesse garantir que todas as instâncias da"left"
cadeia de caracteres foram internadas, mas isso requer análise de todo o aplicativo.)fonte
String
para representar as direções faria quase zero diferença para a quantidade de trabalho envolvido para fazer as alterações. Uma abordagem mais sensata é assumir que o número de direções não mudará e reconhecer que você teria muito trabalho a fazer de qualquer maneira se as regras do jogo mudassem tão fundamentalmente.Como sugerido, você deve usar Enums. No entanto, apenas usar o Enum como um substituto para o Strigns não é suficiente IMHO. No seu exemplo particular, a velocidade do jogador deve ser realmente um vetor por meio da física:
Esse vetor deve ser usado para atualizar a posição do jogador a cada tick.
Você pode combinar isso com uma enumeração para maior legibilidade:
fonte