Aikido

Comment garder les fonctions concises : écrire un code facile à maintenir

Lisibilité

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.

FAQ

Vous avez des questions ?

Comment décomposer les fonctions longues ?

Identifier des responsabilités distinctes au sein de la fonction. Extraire la validation dans des fonctions distinctes. Retirer les calculs pour les placer dans des fonctions pures. Déplacer les opérations d'E/S (base de données, appels API) dans leurs propres fonctions. Chaque fonction extraite doit avoir un objectif clair et unique et un nom descriptif.

Les petites fonctions n'ajoutent-elles pas des frais généraux et ne nuisent-elles pas aux performances ?

Les compilateurs et interprètes modernes intègrent de petites fonctions, éliminant ainsi la surcharge des appels. L'impact sur les performances est négligeable par rapport aux avantages en termes de maintenabilité. Établissez un profil avant d'optimiser. Un code lisible est plus facile à optimiser ultérieurement lorsque vous identifiez les goulets d'étranglement réels.

Qu'en est-il des fonctions comportant de nombreuses étapes séquentielles ?

Les étapes séquentielles suggèrent un flux de travail qui peut être décomposé en fonctions plus petites. Créez des fonctions d'aide pour chaque étape et appelez-les en séquence à partir d'une fonction coordinatrice. Cela rend le flux de travail lisible et chaque étape testable indépendamment.

Comment gérer les fonctions qui nécessitent de nombreux paramètres après l'extraction ?

Transmettez des objets contenant des paramètres connexes plutôt que de longues listes de paramètres. Vous pouvez également vous demander si les fonctions extraites doivent être des méthodes d'une classe qui contient un état partagé. Si une fonction nécessite plus de 6 paramètres, cela peut indiquer une mauvaise abstraction ou des structures de données manquantes.

Dois-je extraire des fonctions même si elles ne sont appelées qu'une seule fois ?

Oui, si l'extraction améliore la lisibilité. Une fonction extraite bien nommée documente ce que fait un bloc de code mieux que des commentaires. L'extraction ponctuelle est utile lorsqu'elle clarifie une logique complexe ou réduit les niveaux d'imbrication dans la fonction mère.

Obtenir la sécurité gratuitement

Sécurisez votre code, votre cloud et votre environnement d'exécution dans un système central.
Trouvez et corrigez rapidement et automatiquement les vulnérabilités.

Aucune carte de crédit n'est requise | Scanner les résultats en 32sec.