Aikido

Perché dovresti utilizzare i ritorni anticipati e le clausole di protezione per ottenere un codice più pulito e leggibile

Leggibilità

Regola

Utilizzo il restituzioni e clausola .
Nidificazione annidamento e parametro parametro convalida
rendono le funzioni più da leggere e da mantenere.

Lingue supportate: 45+

Introduzione

Le clausole di controllo verificano le precondizioni all'inizio di una funzione e restituiscono immediatamente un valore se le condizioni non sono soddisfatte. Ciò appiattisce il livello di nidificazione gestendo i casi di errore in anticipo, lasciando la logica principale non nidificata e di facile lettura. Le funzioni che verificano i parametri a metà del codice o che annidano i percorsi di successo all'interno di più condizioni costringono i lettori a seguire il contesto attraverso numerosi livelli di indentazione.

Perché è importante

Leggibilità del codice: le clausole di protezione rendono visibile il percorso normale alla fine della funzione senza annidamenti. I lettori vedono subito tutte le condizioni di errore, per poi leggere la logica principale a un unico livello di indentazione senza dover tenere a mente condizioni annidate multiple.

Manutenzione e modifica: l'aggiunta di nuove condizioni di validazione o di errore a un codice profondamente annidato richiede un inserimento accurato per evitare di compromettere la logica esistente. Le clausole di protezione inserite all'inizio consentono di aggiungere nuovi controlli senza interferire con la logica principale, riducendo il rischio di introdurre bug.

Esempi di codice

❌ Non conforme:

function processPayment(user, amount) {
    if (user) {
        if (user.isActive) {
            if (amount > 0) {
                if (user.balance >= amount) {
                    user.balance -= amount;
                    return { success: true, newBalance: user.balance };
                } else {
                    return { success: false, error: 'Insufficient funds' };
                }
            } else {
                return { success: false, error: 'Invalid amount' };
            }
        } else {
            return { success: false, error: 'Inactive user' };
        }
    } else {
        return { success: false, error: 'User required' };
    }
}

Perché è sbagliato: i quattro livelli di nidificazione nascondono la logica principale (il calcolo del saldo) nelle profondità della funzione. Ogni condizione di errore aggiunge un altro livello di indentazione, rendendo difficile individuare e comprendere a colpo d'occhio il percorso normale.

✅ Conforme:

function processPayment(user, amount) {
    if (!user) {
        return { success: false, error: 'User required' };
    }
    if (!user.isActive) {
        return { success: false, error: 'Inactive user' };
    }
    if (amount <= 0) {
        return { success: false, error: 'Invalid amount' };
    }
    if (user.balance < amount) {
        return { success: false, error: 'Insufficient funds' };
    }

    user.balance -= amount;
    return { success: true, newBalance: user.balance };
}

Perché è importante: le clausole di protezione verificano tutte le precondizioni con ritorni anticipati, mantenendo la funzione a un unico livello di indentazione. Il percorso normale (addebito sul saldo) è chiaramente visibile alla fine senza annidamenti, rendendo la funzione facile da leggere e modificare.

Conclusione

Con le clausole di protezione, verifica la validità degli input e gestisci i casi di errore all'inizio delle funzioni. Se le condizioni non vengono soddisfatte, esci anticipatamente dalla funzione, invece di annidare il percorso di successo. In questo modo il codice rimane lineare, leggibile e facile da modificare senza compromettere la logica esistente.

Domande frequenti

Hai delle domande?

I ritorni multipli non rendono forse le funzioni più difficili da comprendere?

No. La vecchia regola del “ritorno singolo” risale all’epoca in cui la liberazione delle risorse avveniva manualmente. I linguaggi moderni gestiscono automaticamente la liberazione delle risorse. I ritorni anticipati multipli in caso di errori rendono l’intento più chiaro rispetto al dover seguire il percorso attraverso condizioni annidate per individuare il punto in cui l’esecuzione termina.

Le clausole di protezione dovrebbero generare eccezioni o restituire valori di errore?

Dipende dal contesto. Utilizza le eccezioni per gli errori imprevisti (bug di programmazione, guasti di sistema). Restituisci valori di errore per gli errori di validazione previsti (input non valido, violazioni delle regole di business). Le clausole di protezione funzionano con entrambi gli approcci; l'importante è rilevare rapidamente gli errori all'inizio della funzione.

E per quanto riguarda l'esecuzione di più istruzioni return?

Impatto nullo. I compilatori e gli interpreti ottimizzano le istruzioni di ritorno allo stesso modo, indipendentemente dal numero di istruzioni presenti. I ritorni anticipati possono infatti migliorare le prestazioni, evitando operazioni superflue quando le precondizioni non vengono soddisfatte.

Come posso gestire una logica di validazione complessa nelle clausole di protezione?

Estraete la validazione in funzioni separate: if (!isValidAmount(amount)) return error;. In questo modo le clausole di controllo rimangono leggibili, mentre la logica di validazione complessa viene incapsulata. Ogni funzione di validazione può avere i propri test e la propria documentazione.

E se avessi bisogno di codice di pulizia prima di restituire il risultato?

Utilizza i blocchi `try-finally` o i meccanismi di pulizia specifici del linguaggio (`defer` in Go, `using` in C#, i gestori di contesto in Python). Le clausole `guard` vanno inserite all'interno dei blocchi `try`, mentre le operazioni di pulizia vanno inserite nel blocco `finally`. La struttura rimane piatta grazie ai ritorni anticipati, garantendo al contempo che le operazioni di pulizia vengano eseguite.

Metti in sicurezza ora

Metti in sicurezza il tuo codice, il cloud e il runtime in un unico sistema centralizzato.
Trova e risolvi le vulnerabilità rapidamente e automaticamente.

Nessuna carta di credito richiesta | Risultati della scansione in 32 secondi.