Règle
Conserver fonctions concis.
Les fonctions fonctions sont difficiles difficiles difficiles à comprendre, test, et de maintenance.
Langues prises en charge : 45+Introduction
Les fonctions qui s'étendent sur des centaines de lignes mélangent plusieurs responsabilités, ce qui fait qu'il est difficile de comprendre ce que fait la fonction sans lire chaque ligne. Les fonctions longues gèrent généralement plusieurs aspects, tels que la validation, la logique métier, la transformation des données et la gestion des erreurs, en un seul endroit. Cela viole le principe de la responsabilité unique et crée un code difficile à tester, à déboguer et à modifier sans rompre le comportement existant.
Pourquoi c'est important
Maintenance du code : Les fonctions longues obligent les développeurs à avoir plus de contexte en tête pour comprendre le comportement. La modification d'une partie risque d'en casser une autre, car toute la logique est imbriquée. Les corrections de bogues deviennent risquées car les effets secondaires involontaires sont difficiles à prévoir.
Complexité des tests : Tester une fonction de 200 lignes signifie couvrir tous les chemins de code possibles en un seul test, ce qui nécessite une configuration complexe et de nombreux cas de test. Les fonctions plus petites peuvent être testées indépendamment à l'aide de tests unitaires ciblés, ce qui rend les suites de tests plus rapides et plus fiables.
Exemples de code
❌ Non 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;
}
Pourquoi c'est faux : Cette fonction gère la validation, le calcul, les opérations de base de données, le courrier électronique et l'inventaire. Pour la tester, il faut simuler toutes les dépendances. Toute modification de la logique fiscale ou de la validation nécessite de modifier l'ensemble de cette fonction.
✅ 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;
}Pourquoi cela est-il important ? Chaque fonction a une responsabilité claire. validateOrder() et calculerTotal() peuvent être testés indépendamment sans mocks. createOrder() isole la logique de la base de données. Les opérations de courrier électronique et d'inventaire ne bloquent pas la création des commandes, et les échecs sont traités séparément.
Conclusion
Faites évoluer les API par le biais de modifications additives : ajoutez de nouveaux champs, ajoutez de nouveaux points de terminaison, ajoutez des paramètres facultatifs. Lorsque des changements radicaux sont inévitables, utilisez le versionnage de l'API pour exécuter simultanément les anciennes et les nouvelles versions. Déclassez les anciens champs en indiquant clairement les délais et les guides de migration avant de les supprimer.
.avif)
