Di solito è una buona cosa farlo quando possibile, ma mi piace pensare a questo tipo di lavoro non come "passi", ma come sottoattività .
Una sottoattività è un'unità di lavoro specifica che può essere eseguita: ha una responsabilità specifica e ha definito input (s) e output (s) (pensa alla "S" in SOLID ). Una sottoattività non deve essere riutilizzabile: alcune persone tendono a pensare "Non dovrò mai chiamare questo da qualsiasi altra cosa, quindi perché scriverlo come funzione?" ma questo è un errore.
Proverò anche a delineare i vantaggi e anche il modo in cui si applica alle funzioni nidificate (chiusure) rispetto a un'altra funzione della classe. In generale, consiglierei di non usare le chiusure a meno che tu non ne abbia specificamente bisogno (ci sono molti usi, ma separare il codice in blocchi logici non è uno di questi).
Leggibilità.
Oltre 200 righe di codice procedurale (corpo di una funzione) sono difficili da leggere. Le funzioni da 2 a 20 righe sono facili da leggere. Il codice è per l'uomo.
Annidato o no, si ottiene principalmente il vantaggio della leggibilità, a meno che non si utilizzino molte variabili dall'ambito padre, nel qual caso può essere altrettanto difficile da leggere.
Limitare l'ambito variabile
Avere un'altra funzione ti costringe a limitare l'ambito variabile e passare specificamente ciò di cui hai bisogno.
Questo spesso rende anche il codice della struttura migliore, perché se hai bisogno di una sorta di variabile di stato da un precedente "passo", potresti effettivamente trovare un altro sotto-compito che dovrebbe essere scritto ed eseguito per primo per ottenere quel valore. O in altre parole, rende più difficile scrivere blocchi di codice altamente accoppiati.
La presenza di funzioni nidificate consente di accedere alle variabili nell'ambito genitore dall'interno della funzione nidificata (chiusura). Questo può essere molto utile, ma può anche portare a bug sottili e difficili da trovare poiché l'esecuzione della funzione potrebbe non avvenire nel modo in cui è scritta. Questo è ancora più vero se stai modificando le variabili nell'ambito genitore (una pessima idea, in generale).
Test unitari
Ogni sottoattività, implementata una funzione (o persino una classe) è un pezzo di codice autonomo e testabile. I vantaggi del test unitario e del TDD sono ben documentati altrove.
L'uso di funzioni / chiusure nidificate non consente il test dell'unità. Per me, questo è un rompicapo e il motivo per cui dovresti solo un'altra funzione, a meno che non ci sia una necessità specifica di una chiusura.
Lavorare su un team / Progettazione dall'alto verso il basso
Le attività secondarie possono essere scritte da persone diverse, indipendentemente, se necessario.
Anche da solo, può essere utile durante la scrittura del codice semplicemente invocare alcune attività secondarie che non esistono ancora, mentre si sviluppa la funzionalità principale e preoccuparsi di implementare effettivamente la attività secondaria solo dopo aver saputo che otterrà i risultati necessari in un modo significativo. Questo è anche chiamato progettazione / programmazione top-down.
Riutilizzo del codice
Va bene, quindi, nonostante quello che ho detto prima, a volte in realtà finisce per essere un motivo per riutilizzare una sottoattività per qualcos'altro. Non sto affatto sostenendo il "ismo dell'astronauta dell'architettura "ma solo che scrivendo un codice liberamente accoppiato, potresti finire per beneficiare in seguito del riutilizzo.
Spesso il riutilizzo significa un po 'di refactoring, che è perfettamente previsto, ma il refactoring dei parametri di input in una piccola funzione autonoma è MOLTO più semplice che estrarlo da una funzione di oltre 200 mesi dopo la sua scrittura, che è davvero il mio punto qui.
Se si utilizza una funzione nidificata, il riutilizzo in genere è comunque una questione di refactoring in una funzione separata, il che è ancora una volta il motivo per cui direi che il nidificato non è la strada da percorrere.