¿Alguna vez es una buena idea codificar valores en nuestras aplicaciones? ¿O siempre es correcto llamar a estos tipos de valores dinámicamente en caso de que necesiten cambiarlos?

Comentarios

  • un parámetro de configuración le ayudaría
  • Nunca se sabe cuándo el valor de pi podría cambiar …
  • Hombre, creo que personas como @gabe son la razón por la que esto es una » Regla «. Si repite 3.14 en 20 lugares en su código y luego descubre que realmente necesita más precisión, está jodido. No ‘ no me di cuenta de que esto no era ‘ obvio.
  • Eso fue un poco grosero, @Bill. @Gabe estaba claramente bromeando, pero aparte de eso, la pregunta era sobre la codificación rígida frente a los parámetros de configuración, no usar números mágicos constantes o repetidos en varios lugares.
  • Sí, la codificación fija puede ser una buena idea a veces . Consulte el artículo de Wikipedia sobre el » Softcoding » anti-patrón.

Respuesta

Sí, pero hágalo obvio .

Haga:

No:

Comentarios

  • Que es más limpio, diameter = 2 * radius o diameter = RADIUS_TO_DIAMETER_FACTOR * radius? De hecho, hay casos extremos en los que un número mágico puede ser una mejor solución.
  • No puedo ‘ no estar de acuerdo con esta respuesta es suficiente. Tiendo a pensar en la programación como ser un novelista. Usted cuenta su historia a través del código y si la gente no puede entender la lógica, en mi opinión, su código no tiene valor. Eso ‘ s por qué las convenciones de nomenclatura bien pensadas son esencialmente para la legibilidad. Además, no hay una buena razón para usar números mágicos. Al usar números mágicos, eliminas el » por qué » de la ecuación y hacen que sea más difícil de entender tand. Por ejemplo: » diámetro = 2 * radio » ¿Para qué sirven los dos? Este » diámetro = RADIUS_TO_DIAMETER_FACTOR * radio » tiene mucho más sentido.
  • diámetro = 2 * el radio es directo desde matemáticas de la escuela secundaria. La razón para no nombrar el » 2 » es que para que tenga un valor de cualquier otra cosa, se requeriría un cambio en las leyes de física o matemáticas, o ambas. (Por otro lado, nombrar Pi o la constante de Plancks es un buen movimiento para facilitar la lectura).
  • @Joonas: Pfft. ¿Seguro que te refieres a diameter = radius << 1? Supongo que también podría ser diameter = radius << RADIUS_TO_DIAMETER_BITS_TO_SHIFT.
  • ¿Cómo ‘ sobre algunos diameter = radius.toDiameter()

Respuesta

Lo que encuentro extraño acerca de esta Q & Hasta ahora, nadie ha intentado definir claramente «hard-code» o, lo que es más importante, las alternativas.

tl; dr : Sí, es a veces una buena idea codificar valores de forma rígida, pero no existe una regla simple en cuanto a cuándo ; depende completamente del contexto.

La pregunta se reduce a valores , que entiendo como números mágicos , pero la respuesta a si son una buena idea o no es relativa a para qué se utilizan realmente.

Varios ejemplos de «codificación «Los valores son:

  • Valores de configuración

    Me estremezco cada vez que veo declaraciones como command.Timeout = 600. ¿Por qué 600? ¿Quién decidió eso? ¿Se agotó el tiempo de espera antes y alguien planteó el tiempo de espera como un truco en lugar de solucionar el problema de rendimiento subyacente? ¿O es realmente una expectativa conocida y documentada del tiempo de procesamiento?

    Estos no deberían ser números mágicos o constantes, deberían ser externalizados en un archivo de configuración o base de datos en algún lugar con un nombre significativo, porque su valor óptimo está determinado en gran parte o en su totalidad por el entorno en el que se ejecuta la aplicación.

  • Fórmulas matemáticas

    Las fórmulas suelen ser bastante estáticas, por lo que la naturaleza de los valores constantes en su interior no es particularmente importante. El volumen de una pirámide es (1/3) b * h. ¿Nos importa de dónde vino el 1 o el 3? Realmente no. Un comentarista anterior señaló correctamente que diameter = radius * 2 es probablemente mejor que diameter = radius * RADIUS_TO_DIAMETER_CONVERSION_FACTOR, pero esa es una dicotomía falsa.

    Lo que debería estar haciendo para este tipo de escenario es crear una función . No necesito saber cómo se le ocurrió la fórmula, pero aún necesito saber para qué sirve . Si, en lugar de cualquiera de las tonterías escritas anteriormente, escribo volume = GetVolumeOfPyramid(base, height), entonces de repente todo se vuelve mucho más claro, y está perfectamente bien tener números mágicos dentro la función (return base * height / 3) porque es obvio que son solo parte de la fórmula.

    La clave aquí es, por supuesto, tener Funciones cortas y simples . Esto no funciona para funciones con 10 argumentos y 30 líneas de cálculo. Utilice la composición de funciones o constantes en ese caso.

  • Reglas de dominio / comerciales

    Esta es siempre el área gris porque depende de cuál sea exactamente el valor. La mayoría de las veces, son estos números mágicos particulares los que son candidatos para convertirse en constantes, porque hacen que el programa sea más fácil de entender sin complicar la lógica del programa. Considere la prueba if Age < 19 frente a if Age < LegalDrinkingAge; probablemente puedas averiguar qué está pasando sin la constante, pero es más fácil con la descripción title.

    Estos pueden también convertirse en candidatos para la abstracción de funciones, por ejemplo function isLegalDrinkingAge(age) { return age >= 19 }. Lo único es que a menudo la lógica de su negocio es mucho más complicado que eso, y puede que no tenga sentido comenzar a escribir docenas de funciones con 20-30 parámetros cada una. Si no existe una abstracción clara basada en objetos y / o funciones, entonces recurrir a constantes está bien.

    La advertencia es que, si está trabajando para el departamento de impuestos, se vuelve realmente, realmente oneroso y honestamente inútil escribir AttachForm(FORM_CODE_FOR_SINGLE_TAXPAYER_FILING_JOINTLY_FOR_DEPRECIATION_ON_ARMPIT_HAIR). No vas a hacer eso t, vas a AttachForm("B-46") porque cada desarrollador que alguna vez haya trabajado o trabajará allí sabrá que «B-46» es el código de formulario para un solo contribuyente. archivando bla bla bla – los códigos de formulario son parte del dominio en sí, nunca cambian, por lo que no son realmente números mágicos.

    Por lo tanto, debe usar las constantes con moderación en la lógica empresarial; básicamente tienes que entender si ese «número mágico» es en realidad un número mágico o si es un aspecto bien conocido del dominio. Si es un dominio, entonces no lo codificas a menos que haya un es muy probable que cambie.

  • Códigos de error e indicadores de estado

    Estos nunca están bien para codificarlos, como cualquier pobre bastardo que alguna vez haya sido golpeado con Previous action failed due to error code 46 puede decirte. Si su idioma lo admite, debería utilizar un tipo de enumeración. De lo contrario, normalmente tendrá un archivo / módulo completo lleno de constantes que especifican los valores válidos para un tipo de error en particular.

    Nunca me dejes ver return 42 en un gestor de errores, capiche? Sin excusas.

Probablemente omití varios escenarios, pero creo que eso cubre la mayoría de ellos.

Entonces, sí, a veces es una práctica aceptable para codificar cosas. No seas perezoso al respecto; debería ser una decisión consciente en lugar de un código simple y descuidado.

Comentarios

  • ¡Gracias por el buen desglose! – la mayoría de la gente no ‘ t piensa en todas las opciones. Yo agregaría » Configuración del entorno » – Creo que estos deben evitarse (no codificados), ya que la mayoría de los datos deben colocarse en un archivo de configuración o base de datos. Esto sigue el principio de » mantener los datos y la lógica separados » que es un pilar de MVC o MVVM. string TestServerVar = » foo «; string ProdServerVal = » bar «;

Responder

Hay varias razones para asignar un identificador a un número.

  • Si el número puede cambiar, debe tener un identificador. Es mucho más fácil encontrar NUMBER_OF_PLANETS que buscar cada instancia de 9 y considerar si debe cambiarse a 8. (Tenga en cuenta que los Es posible que las cadenas de caracteres tengan que cambiar si el software alguna vez tiene que usarse en un idioma diferente, y eso es algo difícil de predecir de antemano).
  • Si el número es difícil de escribir de alguna manera. Para constantes como pi, es mejor dar una definición de máxima precisión que volver a escribirla en varios lugares, posiblemente de manera inexacta.
  • Si el número aparece en diferentes lugares. No debería tener que mirar dos usos de 45 en funciones contiguas y preguntarse si significan lo mismo.
  • Si el significado no es reconocible al instante. Es seguro asumir que todo el mundo sabe lo que es 3.14159265 …. No es seguro asumir que todo el mundo reconocerá la constante gravitacional, o incluso pi / 2. («Todo el mundo» aquí depende de la naturaleza del software. Se puede esperar que los programadores de sistemas conozcan la representación octal de los bits de permiso de Unix o similares. En el software de arquitectura naval / marina, verificar el número de Froude de un casco propuesto y la velocidad para ver si es 1.1 o superior se explica perfectamente por sí mismo para cualquiera que debería estar trabajando en él.)
  • Si el contexto no es reconocible . Todo el mundo sabe que hay 60 minutos en una hora, pero multiplicar o dividir por 60 puede no estar claro si no hay indicios inmediatos de que la cantidad es un valor de tiempo o un valor de tasa .

Esto nos brinda criterios para codificar literales. Deben ser inmutables, no difíciles de escribir, ocurrir en un solo lugar o contexto y con un significado reconocible. No tiene sentido al definir 0 como ARRAY_BEGINNING, por ejemplo, o 1 como ARRAY_INCREMENT.

Responder

Como complemento a otras respuestas. Utilice constantes para cadenas cuando sea posible. Por supuesto, no desea tener

const string server_var="server_var"; 

pero debería tener

const string MySelectQuery="select * from mytable;"; 

(asumiendo que en realidad tiene una consulta donde desea obtener todos los resultados de una tabla específica, siempre)

Aparte de eso, use constantes para cualquier número que no sea 0 (generalmente). Si necesita una máscara de bits de permiso de 255, no utilice

const int 8th_bit=255; //or some other obscure naming scheme that equates to 255. 

en su lugar utilice

const int AllowGlobalRead=255; 

Por supuesto, junto con las constantes, sepa cuándo usar enumeradores. El caso anterior probablemente encajaría bien en uno.

Comentarios

  • typedef enum {state_0 = 0, state_1 = 1, state_2 = 2, .. .} … No ‘ t se ría, ‘ lo he visto hecho. ¡Golpea a esa persona en la cabeza con un pescado mojado!
  • @ rápido, por supuesto que ‘ querrías algo más como typedef enum {init_state=0, parse_state=1, evaluation_state=2, ... }
  • THIS_NAMING_CONVENTION_IS_RECOMMENDED_FOR_CONSTANTS
  • Para las cadenas, no ‘ solo desea constantes. Desea colocar cualquier cadena visible para el usuario en algún tipo de archivo de recursos (los detalles dependerán de su plataforma) para que pueda cambiar a otro idioma fácilmente.
  • También podría querer pegar los relacionados con la lógica empresarial cadenas (como consultas SQL) en un archivo de recursos con algún tipo de cifrado u ofuscación. Eso evitará que los usuarios » curiosos » realicen ingeniería inversa en su lógica (o esquema de base de datos).

Respuesta

Depende de lo que consideres la codificación. Si intentas evitar todos los elementos codificados, terminas en un territorio de softcoding y creas un sistema que solo el creador puede administrar (y ese es el ultimate hardcode)

Muchas cosas están codificadas en cualquier marco razonable y funcionan. Es decir, no hay ninguna razón técnica por la que no debería poder cambiar el punto de entrada de una aplicación C # (static void Main ), pero codificación que no crea ningún problema para ningún usuario (excepto la pregunta SO ocasional)

La regla general que utilizo es que cualquier cosa que pueda cambiar y vaya a cambiar, sin afectar el estado de todo el sistema, debería ser configurable.

Entonces, en mi humilde opinión, es una tontería no codificar cosas que nunca cambian (pi, constante gravitacional, una constante en una fórmula matemática – piense en el volumen de una esfera).

También es una tontería no codificar cosas o procesos que tendrán un impacto en su sistema que requerirán programación en cualquier caso, i .e. Es un desperdicio permitir que el usuario agregue campos dinámicos a un formulario, si cualquier campo agregado requiere que el desarrollador de mantenimiento ingrese y escriba algún script que haga que eso funcione. También es estúpido (y lo he visto varias veces en entornos empresariales) crear alguna herramienta de configuración, por lo que nada está codificado, sin embargo, solo los desarrolladores del departamento de TI pueden usarlo, y es solo un poco más fácil usarlo que hacerlo en Visual Studio.

Entonces, en resumen, si una cosa debe estar codificada es una función de dos variables:

  • ¿cambiará el valor
  • ¿Cómo afectará un cambio en el valor al sistema?

Respuesta

¿Alguna vez es una buena idea codificar valores en nuestras aplicaciones?

I codifica los valores solo si los valores están especificados en la Especificación (en una versión final de la especificación), p. ej. La respuesta HTTP OK siempre será 200 (a menos que cambie en el RFC), por lo que verá (en algunos de mis códigos) constantes como:

public static final int HTTP_OK = 200; 

De lo contrario, almaceno constantes en el archivo de propiedades.

La razón por la que especifiqué especificaciones, es que cambiar las constantes en las especificaciones requiere una gestión de cambios, en la cual, las partes interesadas revisarán el cambio y aprobarán / desaprobarán. Nunca sucede de la noche a la mañana y toma meses / años para su aprobación. No olvide que muchos desarrolladores usan especificaciones (por ejemplo, HTTP), por lo que cambiarlo significa romper millones de sistemas.

Respuesta

  • si el valor puede cambiar, y de hecho podría cambiar, entonces codifíquelo siempre que sea posible siempre que el esfuerzo involucrado no exceda el retorno esperado
  • algunos valores no pueden ser codificado en software; siga las pautas de Jonathan en esos casos (raros)

Respuesta

He notado que cada vez que puede extraer datos de su código, mejora lo que queda. Empiezas a notar nuevas refactorizaciones y a mejorar secciones enteras de tu código.

Es una buena idea trabajar para extraer constantes, no lo consideres una regla estúpida, piensa en ello como una oportunidad para codificar mejor.

La mayor ventaja sería la forma en que puede encontrar constantes similares siendo la única diferencia en grupos de código; abstraerlos en matrices me ha ayudado a reducir algunos archivos en un 90% de su tamaño y corregirlos bastante mientras tanto, copia & y pega errores.

Todavía no he visto una ventaja única en no extraer datos.

Respuesta

Recientemente codifiqué una función MySQL para calcular correctamente la distancia entre dos pares lat / long. No puedes simplemente hacer pythagorus; Las líneas de longitud se acercan entre sí a medida que la latitud aumenta hacia los polos, por lo que hay un factor un poco peludo involucrado. El punto es que estaba bastante dividido sobre si codificar el valor que representa el radio de la Tierra en millas.

Terminé haciéndolo, aunque el hecho es que las líneas lat / lng están mucho más juntas en, digamos, la luna. Y mi función subestimaría drásticamente las distancias entre puntos en Júpiter. Supuse que las probabilidades de que se ingrese una ubicación extraterrestre en el sitio web que estoy construyendo son bastante escasas.

Comentarios

Respuesta

Bueno, depende de si su lenguaje está compilado. Si no está compilado, no es gran cosa, simplemente edite el código fuente, incluso si será un poco delicado para un no programador.

Si está programando con un lenguaje compilado, esto claramente no es una buena idea, porque si las variables cambian, tendrá que volver a compilar, lo cual es una gran pérdida de tiempo si desea ajustar esta variable.

No es necesario crear un control deslizante o una interfaz para cambiar dinámicamente su variable, pero lo mínimo que puede hacer es un archivo de texto.

Por ejemplo, con mi proyecto ogro, siempre estoy usando la clase ConfigFile para cargar una variable que he escrito en un archivo de configuración.

Respuesta

Dos ocasiones en las que las constantes están (al menos en mi opinión) bien:

  1. Constantes que no se relacionan con nada más; puede cambiar esas constantes siempre que lo desee sin tener que cambiar nada más. Ejemplo: el ancho predeterminado de una columna de cuadrícula.

  2. Constantes absolutamente inmutables, precisas y obvias, como «número de días por semana». days = weeks * 7 Reemplazar 7 con una constante DAYS_PER_WEEK apenas proporciona ningún valor.

Responder

Estoy completamente de acuerdo con Jonathan, pero como todas las reglas hay excepciones …

«Número mágico en la especificación: Número mágico en el código»

Básicamente establece que cualquier número mágico que permanezca en la especificación después de intentos razonables de obtener un contexto descriptivo para ellos debe reflejarse como tal en el código. Si los números mágicos permanecen en el código, se deben hacer todos los esfuerzos posibles para aislarlos y vincularlos claramente con su punto de origen.

He realizado algunos contratos de interfaz en los que es necesario completar mensajes con valores mapeados de la base de datos. En la mayoría de los casos, el mapeo es bastante sencillo y encajaría en las pautas generales de Jonathan, pero he encontrado casos en los que la estructura del mensaje de destino era simplemente terrible.Más del 80% de los valores que debían transmitirse en la estructura eran constantes impuestas por la especificación del sistema distante. esto, junto con el hecho de que la estructura del mensaje era gigantesca, hizo que MUCHAS de estas constantes tuvieran que ser pobladas. En la mayoría de los casos, no proporcionaron un significado o una razón, simplemente dijeron «poner M aquí» o «poner 4.10.53.10100.889450.4452 aquí». Tampoco intenté poner un comentario junto a todos ellos, habría hecho que el código resultante fuera ilegible. Sin embargo, me aseguré de que las secciones de código donde aparecen estos valores mágicos estén correctamente aisladas y que sus contenedores (clases, paquetes) tengan el nombre apropiado para apuntar directamente a la especificación que los aplica.

Dicho esto, cuando piense en es … se trata básicamente de hacerlo obvio

Respuesta

Si está codificando el valor de la constante gravitacional de la Tierra, a nadie le va a importar. Si codifica la dirección IP de su servidor proxy, tendrá problemas.

Comentarios

  • Es posible que necesite más precisión para earth ‘ s constante gravitacional, por lo que codificarla varias veces podría generar problemas.
  • Peter Noone? De Herman ‘ s Hermits ?
  • La aceleración gravitacional en la Tierra es de aproximadamente 9.81 m / s ^ 2 para la mayoría de latitudes y altitudes (por supuesto, si ‘ está buscando petróleo bajo tierra, o disparar misiles balísticos intercontinentales sobre el Polo Norte, conocer la variación en la gravedad es muy importante para muchos más decimales), siendo la aceleración gravitacional en otros planetas un número diferente, pero hasta donde yo sé, la constante gravitacional es constante alrededor del universo. Hay mucha física que tendría que cambiar si g fuera variable.

Respuesta

La mayoría de las veces no, pero creo que vale la pena señalar que Tendré más problemas cuando empiece a duplicar el valor codificado. Si no lo duplica (por ejemplo, lo usa solo una vez en la implementación de una clase), entonces no usar una constante podría estar bien.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *