Buenas prácticas de programación: evita los números mágicos

Hoy comenzamos una categoría de artículos explicando buenas prácticas de programación. Es importante tenerlas en cuenta a la hora de escribir código porque será mucho más fácil de leer y mantener en un futuro, tanto por nosotros como por otras personas. Comenzamos con un problema típico: los números mágicos.

¿Qué son los números mágicos?

Los números mágicos son aquellos que aparecen en medio del codigo y no se sabe muy bien por qué o de dónde vienen exactamente. Pongamos un ejemplo:

void setup() {
  pinMode(8, OUTPUT); // red LED
  pinMode(9, OUTPUT); // blue LED
}
void loop() {
  digitalWrite(8, HIGH);
  delay(200);
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH);
  delay(200);
  digitalWrite(9, LOW);
}
Este es un código bastante corto y sencillo pero nos valdrá como explicación. Simplemente vamos encendiendo alternativamente dos salidas que encienden dos LEDs distintos, un LED rojo y un LED azul.
Estamos utilizando dos pines, inicializados en el setup(): el pin 8 y el pin 9, y además tenemos un retardo entre el encendido alternativo de 200 milisegundos.
¿Qué pasaría si tuviéramos que modificar el código porque hemos cambiado las conexiones o quisiéramos cambiar el retardo entre el encendido? Nos tocaría buscar en todo el código todos los puntos donde se utilizan esos pines o el retardo, que es todo el texto marcado en rojo.

Cómo evitar los números mágicos

En vez de poner en el código directamente valores que nos va a ser difícil recordar de dónde vienen, es mucho más conveniente definir constantes al comienzo del código definiendo estos valores. De esta manera, el código quedaría:
const int PIN_LED_RED=8;
const int PIN_LED_BLUE=9;
const int DELAY=200;

void setup() {
  pinMode(PIN_LED_RED, OUTPUT);
  pinMode(PIN_LED_BLUE, OUTPUT);
}

void loop() {
  digitalWrite(PIN_LED_RED, HIGH);
  delay(DELAY);
  digitalWrite(PIN_LED_RED, LOW);
  digitalWrite(PIN_LED_BLUE, HIGH);
  delay(DELAY);
  digitalWrite(PIN_LED_BLUE, LOW);
}
Ahora cuando queremos encender el LED rojo, no escribimos:
digitalWrite(8, HIGH);
Sino que escribimos:
digitalWrite(PIN_LED_RED, HIGH);
Esta segunda sentencia es mucho más clara y no tenemos que recordar exactamente a qué pin corresponde cada cosa: la sentencia se explica sola.
Además, si en algún momento el pin del LED rojo lo conectamos a otro pin, no tenemos que cambiar en 3 sentencias, sino que simplemente cambiamos en la constante donde hemos definido el número de pin que utiliza el LED (marcado en verde).

Cómo definir constantes

En casi todos los lenguajes, las constantes se definen de una manera concreta. En Java (que es el lenguaje en el que escribimos los programas de Arduino):
const int PIN_LED_BLUE=9;
Tenemos:
  • El modificador «const«. ¿Y para qué sirve este modificador? Para que el compilador sepa que este valor guardado en memoria es fijo y si en alguna parte del código, por error, lo intentamos modificar nos dará un error.
  • El tipo de dato. En este caso, es un número entero («int«).
  • El nombre de la constante («PIN_LED_BLUE«). El convenio es que los nombres de las constantes se escriben en mayúsculas, para distinguirlas de las variables normales.
  • Dado que es una constante, le tenemos que dar un valor en el mismo momento en que la definimos porque luego no lo podemos modificar.

Comentarios

3 respuestas a «Buenas prácticas de programación: evita los números mágicos»

  1. Avatar de Ardutipis
    Ardutipis

    Hola Jordi.

    El uso de esas «buenas prácticas» queda algo cojo cuando:
    1) Declaras como int un pin que por ejemplo en el caso de Arduino UNO no va a exceder del 13 o en NANO de 12.
    2) Llamas a una constante igual que una funcion nativa, DELAY. Sí, no da error porque está toda en mayúscula, pero es como llamar a una variable PARSEINT y ponerla dentro de dicha función, o llamar a una variable boolean: BOOLEAN

    Es una mera opinión personal. Cada cual programa como quiere.
    Saludos.

    1. Avatar de Jordi
      Jordi

      Hola Ardutipis,

      Muchas gracias por tu comentario y lo tengo en cuenta para futuros posts:
      -Respecto al punto 1, ¿cuál sería tu sugerencia en este caso?
      -Respecto al punto 2, totalmente de acuerdo que no es conveniente llamar una constante igual (o incluso parecido) a una función para evitar posibles confusiones.

      Un saludo

    2. Avatar de Axis
      Axis

      «Cada cual programa como quiere» y por eso el mantenimiento del software es una pesadilla en las organizaciones. No, el tema de buenas prácticas y estandarización es un tema que se debe tomar tan en serio como la ortografía y la redacción si no se vuelve un dolor de cabeza para los proyectos.

Deja una respuesta

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