Este es un tema un tanto controvertido, y supongo que hay tantas opiniones como programadores. Pero en aras de eso, quiero saber cuáles son las prácticas comunes en los negocios (o en sus lugares de trabajo).
En mi lugar de trabajo tenemos unas estrictas pautas de codificación. Una sección de eso está dedicada a cadenas / números mágicos. Establece (para C #):
No use valores literales, ya sean numéricos o de cadenas, en su código que no sea para definir constantes simbólicas. Use el siguiente patrón para definir constantes:
public class Whatever { public static readonly Color PapayaWhip = new Color(0xFFEFD5); public const int MaxNumberOfWheels = 18; }
Hay excepciones: los valores 0, 1 y nulo casi siempre se pueden usar de forma segura. Muy a menudo, los valores 2 y -1 también están bien. Las cadenas destinadas al registro o al rastreo están exentas de esta regla. Los literales están permitidos cuando su significado es claro por el contexto, y no están sujetos a cambios futuros.
mean = (a + b) / 2; // okay
WaitMilliseconds(waitTimeInSeconds * 1000); // clear enough
Una situación ideal sería algún documento de investigación oficial que muestre los efectos sobre la legibilidad / mantenibilidad del código cuando:
- Los números / cuerdas mágicas están por todas partes
- Las cadenas / números mágicos se reemplazan por declaraciones constantes razonablemente (o en diferentes grados de cobertura), y por favor no me griten por usar "razonablemente", sé que todos tienen una idea diferente de lo que es "razonablemente"
- Las cadenas / números mágicos se reemplazan en exceso y en lugares donde no tendrían que estar (vea mi ejemplo a continuación)
Me gustaría hacer esto para tener algunos argumentos con base científica cuando discuta con uno de mis colegas, quien va al punto de declarar constantes como:
private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;
Otro ejemplo sería (y este está en JavaScript):
var someNumericDisplay = new NumericDisplay("#Div_ID_Here");
¿Pega ID de DOM encima de su archivo javascript si esa ID se usa solo en 1 lugar?
He leído los siguientes temas:
StackExchange
StackOverflow
Bytes IT Community
Hay muchos más artículos, y después de leerlos, surgen algunos patrones.
Entonces, mi pregunta es ¿debería usar cadenas y números mágicos en nuestro código? Estoy buscando específicamente respuestas de expertos que estén respaldadas por referencias si es posible.
fuente
NumberTen = 10
Eso no tiene sentido ya que el número 10 no será redefinido.MaxRetryCount = 10
Eso tiene un punto a que podemos querer cambiar el recuento máximo de reintentos.private const char SemiColon = ';';
Tonto.private const char LineTerminator = ';'
; Inteligente.Respuestas:
El argumento que necesita hacer con su colega no se trata de nombrar un espacio literal como
Space
sino de su mala elección de nombre para sus constantes.Digamos que el trabajo de su código es analizar una secuencia de registros que contienen campos separados por punto
a;b;c
y coma ( ) y están separados por espacios (a;b;c d;e;f
). Si quien escribió su especificación lo llama dentro de un mes y le dice "nos equivocamos, los campos en los registros están separados por símbolos de tubería (a|b|c d|e|f
)", ¿qué hace?Según el esquema de valor como nombre que prefiere su colega, tendría que cambiar el valor del literal (
SemiColon = '|'
) y vivir con el código que continúa utilizandoSemiColon
para algo que ya no es punto y coma. Eso conducirá a comentarios negativos en las revisiones de código . Para disminuir eso, puede cambiar el nombre del literal aPipeSymbol
y pasar y cambiar cada aparición deSemiColon
aPipeSymbol
. A ese ritmo, también podría haber usado un punto y coma literal (';'
) en primer lugar, porque tendrá que evaluar cada uso individualmente y realizará la misma cantidad de cambios.Identificadores para las constantes tienen que ser descriptivo de lo que el valor lo hace , no lo que el valor es , y ahí es donde su colega ha hecho un giro a la izquierda en la maleza. En la aplicación de división de campo descrita anteriormente, el propósito del punto y coma es un separador de campo, y las constantes deben nombrarse en consecuencia:
De esta manera, cuando cambia el separador de campo, cambia exactamente una línea de código, la declaración de la constante. Alguien que vea el cambio verá solo esa línea e inmediatamente comprenderá que el separador de campo cambió de un punto y coma a un símbolo de tubería. El resto del código, que no necesitaba cambiar porque estaba usando una constante, sigue siendo el mismo, y el lector no tiene que buscarlo para ver qué más se le hizo.
fuente
#define one 1 #define two 2
etc. (o el equivalente en la oficina de correos del Reino Unido Coral, el idioma elegido). Se corrió la#define one 8 #define two 16
;
a|
.public static final String MY_KEY_NAME = "MyKeyName"
CSV_RECORD_SEPARATOR
,TSV_RECORD_SEPARATOR
, etc.).Definir punto y coma como una constante es redundante, porque el punto y coma ya es constante por sí mismo . No va a cambiar nunca.
No es como si un día alguien anunciara "cambio de terminología, + es el nuevo punto y coma ahora", y su colega se apresurará a actualizar la constante (se rieron de mí, mírelos ahora).
También hay una cuestión de consistencia. Le garantizo que su
NumberTen
constante NO será utilizada por todos (la mayoría de los codificadores no están locos), por lo que de todos modos no servirá para el propósito que se esperaba. Cuando llega el apocalipsis y "diez" se redimensiona globalmente a 9, actualizar la constante NO será el truco, porque todavía te dejará con un montón de10
s literales en tu código, por lo que ahora el sistema se vuelve totalmente impredecible incluso dentro del alcance de una suposición revolucionaria de que "diez" significa "9".Almacenar todas las configuraciones como consts es algo en lo que también tengo dudas. Uno no debe hacer esto a la ligera.
¿Qué ejemplos de este tipo de uso hemos reunido hasta ahora? Terminador de línea ... recuento máximo de reintentos ... número máximo de ruedas ... ¿estamos seguros de que nunca cambiarán?
El costo es que cambiar la configuración predeterminada requiere volver a compilar una aplicación y, en algunos casos, incluso sus dependencias (ya que los valores numéricos constantes pueden codificarse durante la compilación).
También está el aspecto de prueba y burla. Definió la cadena de conexión como una constante, pero ahora no puede burlarse del acceso a la base de datos (establecer una conexión falsa) en la prueba de su unidad.
fuente
’
(comilla simple izquierda, Unicode 8217 ) para aplicaciones compatibles con mostrar un glifo diferente para la marca curva. Siendo que Europa usa comas de la misma manera que los estadounidenses usan puntos como punto decimal, me siento un poco indeciso al declarar "no ... nunca".DecimalPoint
constante - pero noComma
oPeriod
constantes. Es una gran diferencia: el primero denota una función , un rol o un propósito del valor. "Punto y coma" o "coma" no entran en esa categoría.Por lo tanto, su colega apunta a una entrada diaria de WTF. Esas definiciones son tontas y redundantes. Sin embargo, como han señalado otros, las siguientes definiciones no serían tontas ni redundantes:
Los números y cadenas "mágicos" son constantes que tienen un significado más allá de su valor literal inmediato. Si la constante
10
tiene un significado más allá de "diez cosas" (digamos como un código para una operación específica o condición de error), es cuando se convierte en "mágico" y debe ser reemplazado por una constante simbólica que describa ese significado abstracto.Más allá de describir claramente la intención, las constantes simbólicas también te ahorran algunos dolores de cabeza cuando escribes mal un literal. Una simple transposición de "CVS" a "CSV" en una línea de código pasó por las pruebas unitarias y el control de calidad y llegó a producción, donde causó el fallo de una operación en particular. Sí, obviamente la unidad y las pruebas de control de calidad estaban incompletas y ese es su propio problema, pero el uso de una constante simbólica habría evitado esa acidez estomacal por completo.
fuente
No debería haber nada controvertido al respecto. El punto no es si usar números mágicos o no, el punto es tener un código legible.
Considere la diferencia entre:
if(request.StatusCode == 1)
yif(request.HasSucceeded)
. En este caso, diría que este último es mucho más legible, pero eso no significa que nunca pueda tener un código similarint MaxNumberOfWheels = 18
.PD: Por eso odio absolutamente las pautas de codificación. Los desarrolladores deben ser lo suficientemente maduros como para ser capaces de hacer juicios de este tipo; no deberían dejarlo a un texto formado por Dios sabe quién.
fuente