Hay una diferencia enorme entre código que funciona y código limpio. El primero pasa los tests y hace lo que tiene que hacer hoy. El segundo, además, se puede leer, modificar y ampliar sin miedo dentro de tres meses, cuando ya no recuerdes por qué escribiste esa línea de esa manera. "Clean Code" (código limpio) es el nombre que se le da a un conjunto de prácticas, popularizadas sobre todo por el libro de Robert C. Martin, orientadas a que el código priorice la legibilidad tanto como la funcionalidad.

No hace falta memorizar un libro entero para empezar a aplicarlo. Con un puñado de reglas concretas, aplicadas de forma consistente, la diferencia en la calidad de tu código es notable desde el primer día.

Por qué importa el código limpio

El código se escribe una vez, pero se lee decenas de veces: por ti mismo, por quien lo revisa, por quien lo modifica meses después. Un código difícil de leer no solo ralentiza a otros, también te ralentiza a ti: la mayor parte del tiempo de un programador no se va en escribir código nuevo, sino en entender código ya existente para poder modificarlo con seguridad. De hecho, saber escribir código legible es una de las señales que distinguen a un perfil senior de uno junior: no por dominar más trucos del lenguaje, sino por escribir código que otros pueden entender sin tener que preguntarte.

Regla 1: nombres que dicen lo que hacen

El nombre de una variable, función o clase debería responder a la pregunta "¿qué contiene o qué hace esto?" sin necesidad de leer su implementación. Nombres como d, tmp, data2 o procesar() obligan a quien lee el código a bucear en los detalles para entender algo que un buen nombre habría explicado directamente. La regla práctica es sencilla: si necesitas un comentario para explicar qué hace una variable, casi siempre es mejor señal de que el nombre está mal elegido que de que falta el comentario.

Regla 2: funciones pequeñas con una sola responsabilidad

Una función debería hacer una cosa, y hacerla bien. Cuando una función calcula un total, aplica un descuento y además imprime el resultado por consola, está mezclando responsabilidades que deberían estar separadas: si mañana necesitas calcular el total sin aplicar el descuento, o sin imprimir nada, tienes que reescribir la función entera en vez de reutilizar una pieza más pequeña. Compara las dos versiones del mismo cálculo:

javascript
function calc(d) {
  let t = 0;
  for (let i = 0; i < d.length; i++) {
    t += d[i].p * d[i].q;
  }
  if (t > 100) {
    t = t - t * 0.1;
  }
  console.log("Total: " + t);
  return t;
}
javascript
function calcularSubtotal(lineasPedido) {
  return lineasPedido.reduce(
    (total, linea) => total + linea.precio * linea.cantidad,
    0
  );
}

function aplicarDescuentoPorVolumen(subtotal) {
  const UMBRAL_DESCUENTO = 100;
  const PORCENTAJE_DESCUENTO = 0.1;
  const superaElUmbral = subtotal > UMBRAL_DESCUENTO;
  return superaElUmbral
    ? subtotal * (1 - PORCENTAJE_DESCUENTO)
    : subtotal;
}

function calcularTotalPedido(lineasPedido) {
  const subtotal = calcularSubtotal(lineasPedido);
  return aplicarDescuentoPorVolumen(subtotal);
}

La versión "antes" tiene varios problemas típicos: el nombre calc no dice qué calcula, d, t, p y q no dicen qué contienen, el 10% de descuento aparece como un número mágico sin explicación, y la función mezcla cálculo con un efecto secundario (console.log) que no tiene nada que ver con calcular un total. La versión "después" separa cada responsabilidad en su propia función con un nombre descriptivo, saca el porcentaje de descuento a una constante con nombre, y elimina el console.log de la lógica de cálculo: si alguien necesita mostrar el resultado, puede hacerlo fuera, donde corresponda.

Regla 3: evita los números y strings mágicos

Un "número mágico" es un valor literal (como el 100 o el 0.1 del ejemplo anterior) que aparece directamente en el código sin explicación de qué representa. El problema no es solo de legibilidad: si ese mismo valor se usa en tres sitios distintos y hay que cambiarlo, es fácil olvidar actualizarlo en alguno de ellos. Extraerlo a una constante con nombre (UMBRAL_DESCUENTO) resuelve ambos problemas a la vez.

Regla 4: comentarios que explican el porqué, no el qué

Un comentario como // suma los precios encima de una línea que claramente suma precios no aporta nada; si el código está bien nombrado, se explica solo. Los comentarios útiles explican el porqué de una decisión que no es obvia a partir del código: por qué se eligió un algoritmo concreto, por qué hay una excepción a una regla general, o qué limitación externa obliga a una solución que de otra forma parecería rara. Si te encuentras escribiendo muchos comentarios de tipo "qué hace esto", es una señal de que el código en sí debería ser más claro.

Clean Code y testing van de la mano

Una consecuencia práctica de aplicar estas reglas es que el código se vuelve mucho más fácil de probar. Las funciones pequeñas con una única responsabilidad, como calcularSubtotal o aplicarDescuentoPorVolumen del ejemplo, se pueden testear de forma aislada, sin depender de mocks complicados ni de efectos secundarios. Si todavía no escribes tests de forma habitual, una introducción práctica a Jest es un buen siguiente paso, porque verás en la práctica cómo el código limpio y el código testeable son, en realidad, la misma cosa vista desde dos ángulos distintos.

Cómo empezar a aplicarlo sin agobiarte

No intentes aplicar todas las reglas de golpe a un proyecto grande ya existente; es una forma segura de frustrarte y no terminar nada. Aplícalas de forma incremental: la próxima vez que abras un archivo para arreglar un bug, aprovecha para renombrar una variable poco clara o partir una función demasiado larga, aunque no tenga relación directa con el bug que estás arreglando. Con el tiempo, este hábito se vuelve automático, y es exactamente el tipo de criterio que se evalúa (aunque no siempre de forma explícita) en una entrevista técnica, cuando te preguntan por qué tomaste una decisión concreta en tu código.

JR

Javier Rodríguez Fernández

Programador con Grado Superior en Desarrollo de Aplicaciones Multiplataforma (DAM). Escribe en DevPulso sobre programación aplicada, sin relleno.