El helper ya existía: buscar antes de escribir
Formatear una fecha, armar una URL con parámetros, calcular si algo está vigente. Todo eso ya estaba escrito en el repositorio, y la copia nueva no es sólo trabajo duplicado: es una segunda versión que se va a comportar distinto.
El comentario llega en una línea: «esto ya existe en shared». Duele un poco porque uno acaba
de escribirlo y funciona. Pero el problema no es el tiempo perdido —eran veinte minutos—, sino lo
que pasa dentro de seis meses.
Cuando hay dos funciones que hacen casi lo mismo, alguien arregla un bug en una. La otra sigue andando mal, y nadie sabe que existe.
Lo que siempre ya estaba escrito
| Lo que se escribió de nuevo | Dónde estaba | Qué hacía distinto la versión vieja |
|---|---|---|
| Formatear un importe | Utilidad compartida de moneda | Contemplaba el separador y la moneda por país |
| Armar una URL con parámetros | Constructor del módulo de navegación | Escapaba los valores y respetaba la marca activa |
| Saber si una promoción está vigente | Servicio de dominio | Comparaba en la zona horaria correcta, no en la del navegador |
| Agrupar una lista por una clave | Utilidad genérica del proyecto | Manejaba la clave ausente en vez de crear un grupo `undefined` |
Ese es el patrón: la versión nueva no está mal, está incompleta. Cubre el caso de quien la escribió y no los tres casos raros que la vieja fue absorbiendo con el tiempo. Y esos casos raros son, casi siempre, bugs que alguien ya reportó.
Por qué no se busca
Nadie duplica por comodidad. Las razones que aparecen son concretas y tienen solución.
Las cuatro razones reales
- No se sabe cómo se llama. Buscar
formatDateno encuentratoDisplayDate. La búsqueda por nombre falla justo cuando el vocabulario del proyecto no es el propio. - Está en un módulo que uno no conoce. En un repositorio grande, media base de código es territorio ajeno.
- Se encontró, y no parecía servir. Tenía un parámetro de más o devolvía otra forma. Extenderla se siente más riesgoso que escribir una nueva.
- Apuro. El ticket estaba vencido ayer.
Cuando existe pero no alcanza
El caso interesante no es el helper idéntico sino el parecido. Ahí hay tres salidas y la equivocada es la primera.
Antes de seguir, predecí
La señal de que hay que separar en vez de extender es el nombre: si para nombrar bien la función extendida hace falta una conjunción, son dos cosas distintas.
Lo que hace el equipo para que se encuentre
Esto no se arregla pidiéndole a la gente que busque mejor. Se arregla haciendo que lo compartido sea encontrable.
Cuatro cosas que bajan la duplicación de verdad
- Un lugar obvio. Un solo módulo compartido por tipo de cosa, no utilidades desperdigadas por cada carpeta de funcionalidad.
- Vocabulario acordado. Si el equipo dice “vigencia”, que la función se llame así y no
validityen un módulo yactiveRangeen otro. - Que el review lo señale sin culpa. “Esto ya está en X” es información, no una corrección. El costo de escribirlo de nuevo ya se pagó; lo que se evita es el segundo mantenimiento.
- Borrar la duplicación cuando aparece. Encontrar dos versiones y dejarlas porque “las dos funcionan” es la forma en que se llega a cinco.
Más a fondo · nivel seniorEl reuso también tiene un costo
La otra cara: no todo lo parecido debe unificarse. Dos funciones que hoy hacen lo mismo por coincidencia, pero pertenecen a dominios distintos, se van a separar en el futuro, y unificarlas crea un acoplamiento entre partes que no tienen nada que ver. La pregunta no es “¿el código es igual?” sino “¿si cambia una, tiene que cambiar la otra?”. Si la respuesta es no, son dos cosas.
Lo que ya estaba escrito
Hay 4 problemas en este cambio. Tocá la línea donde creas que está.
| 1 | 1 | ||
| 2 | 2 | ||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
BloqueaEl formato de fecha tampoco, y acá el bug es más fino Además de duplicar algo que existe, no rellena con ceros: el 5 de marzo sale como 5/3/2026 y el 15 como 15/3/2026. En un CSV que alguien va a abrir en una planilla, esas dos columnas ordenan distinto. El formateador compartido ya resuelve eso, y además respeta la configuración regional del usuario. | |||
| 7 | |||
| 8 | |||
| 9 | |||
BloqueaEl escapado de CSV es la tercera cosa que ya estaba Y está mal de una forma conocida: un nombre con comillas adentro rompe el archivo, y uno con un salto de línea también. Es exactamente el tipo de problema que una utilidad compartida ya resolvió después de que alguien lo sufriera, y por eso conviene buscar antes: lo que se encuentra no es sólo código, es la lista de casos borde que alguien ya pagó. | |||
| 10 | |||
| 11 | |||
| 12 | |||
PreguntaCómo se habría evitado en dos minutos Buscar «format» y «csv» en el paquete compartido antes de escribir nada. Los lugares donde siempre ya está algo escrito son los mismos: formateo de números y fechas, manejo de moneda, validaciones de identificadores del país, y todo lo que tenga que ver con serializar. Antes de escribir una función que suena genérica, conviene asumir que existe. | |||
| 13 | |||
| 14 | |||
| 15 | |||
| 16 | |||
| 17 | |||
| 18 | |||
Cuatro utilidades escritas a mano, tres con bugs que la versión compartida ya no tiene.
Que lo existente se encuentre
Cierre
Autoevaluación
¿Lo entendiste?
Práctica
BloqueaEl formato de moneda ya existe, y éste ignora la moneda
Hay un formatMoney en el paquete compartido que recibe el monto y la moneda. Éste escribe el signo peso a mano, así que una factura en dólares o en euros va a salir mal. Y como el reporte se ve bien en las pruebas locales, donde todo es en pesos, nadie lo va a notar hasta que un cliente lo reciba.