Regla
Mantenga funciones concisas.
Las funciones largas funciones son difíciles de entender, prueba, y mantener.
Idiomas compatibles: 45+Introducción
Las funciones que abarcan cientos de líneas mezclan múltiples responsabilidades, lo que dificulta la comprensión de lo que hace la función sin leer cada línea. Las funciones largas suelen manejar múltiples aspectos, como la validación, la lógica de negocio, la transformación de datos y la gestión de errores, todo en el mismo sitio. Esto viola el principio de responsabilidad única y crea código difícil de probar, depurar y modificar sin romper el comportamiento existente.
Por qué es importante
Mantenimiento del código: Las funciones largas obligan a los desarrolladores a tener más contexto en la cabeza para entender el comportamiento. Si se modifica una parte, se corre el riesgo de romper otra, ya que toda la lógica está entrelazada. Las correcciones de errores son arriesgadas, ya que es difícil predecir los efectos secundarios no deseados.
Complejidad de las pruebas: Probar una función de 200 líneas significa cubrir todas las posibles rutas de código en una prueba, lo que requiere una configuración compleja y numerosos casos de prueba. Las funciones más pequeñas pueden probarse de forma independiente con pruebas unitarias específicas, lo que agiliza las suites de pruebas y las hace más fiables.
Ejemplos de códigos
❌ No conforme:
async function processOrder(orderData) {
if (!orderData.items?.length) throw new Error('Items required');
if (!orderData.customer?.email) throw new Error('Email required');
const subtotal = orderData.items.reduce((sum, item) =>
sum + (item.price * item.quantity), 0);
const tax = subtotal * 0.08;
const total = subtotal + tax + (subtotal > 50 ? 0 : 9.99);
const order = await db.orders.create({
customerId: orderData.customer.id,
total: total
});
await emailService.send(orderData.customer.email, `Order #${order.id}`);
await inventory.reserve(orderData.items);
return order;
}
Por qué está mal: Esta función maneja la validación, el cálculo, las operaciones de base de datos, el correo electrónico y el inventario. Las pruebas requieren simular todas las dependencias. Cualquier cambio en la lógica fiscal o la validación requiere modificar toda esta función.
✅ Conforme:
function validateOrder(orderData) {
if (!orderData.items?.length) throw new Error('Items required');
if (!orderData.customer?.email) throw new Error('Email required');
}
function calculateTotal(items) {
const subtotal = items.reduce((sum, item) =>
sum + (item.price * item.quantity), 0);
return subtotal + (subtotal * 0.08) + (subtotal > 50 ? 0 : 9.99);
}
async function createOrder(customerId, total) {
return await db.orders.create({ customerId, total });
}
async function processOrder(orderData) {
validateOrder(orderData);
const total = calculateTotal(orderData.items);
const order = await createOrder(orderData.customer.id, total);
// Non-critical operations in background
emailService.send(orderData.customer.email, `Order #${order.id}`).catch(console.error);
return order;
}Por qué es importante: Cada función tiene una responsabilidad clara. validarPedido() y calcularTotal() pueden probarse independientemente sin mocks. crearOrden() aísla la lógica de la base de datos. Las operaciones de correo electrónico e inventario no bloquean la creación de pedidos, y los fallos se gestionan por separado.
Conclusión
Haga evolucionar las API mediante cambios aditivos: añada nuevos campos, nuevos puntos finales o parámetros opcionales. Cuando los cambios de última hora sean inevitables, utilice el control de versiones de la API para ejecutar simultáneamente versiones antiguas y nuevas. Deje obsoletos los campos antiguos con plazos claros y guías de migración antes de eliminarlos.
.avif)
