Tecniche per ridurre al minimo il numero di argomenti di funzione

11

In Clean Code, è scritto che "il numero ideale di argomenti per una funzione è zero". I motivi per cui sono spiegati e hanno senso. Quello che sto cercando sono le tecniche per rifattorare i metodi con 4 o più argomenti per risolvere questo problema.

Un modo è quello di estrarre gli argomenti in una nuova classe, ma questo porterebbe sicuramente a un'esplosione di classi? E queste classi probabilmente finiranno con nomi che violano alcune delle regole di denominazione (che terminano con "Dati" o "Informazioni" ecc.)

Un'altra tecnica è quella di rendere variabili utilizzate da più funzioni una variabile membro privata per evitare di passarle, ma che espande l'ambito della variabile, possibilmente tale che sia aperto a funzioni che in realtà non ne hanno bisogno.

Cerca solo modi per ridurre al minimo gli argomenti della funzione, avendo accettato i motivi per cui è una buona idea farlo.

    
posta Neil Barnwell 23.09.2016 - 10:59
fonte

4 risposte

14

La cosa più importante da ricordare è che quelle sono linee guida, non regole.

Ci sono casi in cui un metodo semplicemente deve prendere un argomento. Pensa al metodo + per i numeri, ad esempio. Oppure il metodo add per una raccolta.

In effetti, si potrebbe persino obiettare che ciò che significa aggiungere due numeri dipende dal contesto, ad es. in ℤ 3 + 3 == 6 , ma in ℤ | 5 3 + 3 == 2 , quindi l'operatore di addizione dovrebbe essere un metodo su un oggetto di contesto che accetta due argomenti invece di un metodo su numeri che accettano un argomento.

Allo stesso modo, un metodo per confrontare due oggetti deve essere un metodo di un oggetto che prende l'altro come argomento, o un metodo del contesto, prendendo due oggetti come argomenti, quindi non ha senso avere un metodo di confronto con meno di un argomento.

Detto questo, ci sono un paio di cose che possono essere fatte per ridurre il numero di argomenti per un metodo:

  • Rendi più semplice il metodo : forse, se il metodo richiede molti argomenti, sta facendo troppo?
  • Un'astrazione mancante : se gli argomenti sono strettamente correlati, forse appartengono insieme e c'è un'astrazione che ti manca? (Esempio di libro di testo canonico: anziché due coordinate, passa un oggetto Point , oppure invece di passare il nome utente e l'e-mail, passa un oggetto IdCard .)
  • Stato oggetto : se l'argomento è necessario con più metodi, forse dovrebbe essere parte dello stato dell'oggetto. Se è necessario solo da alcuni dei metodi ma non da altri, forse l'oggetto sta facendo troppo e dovrebbe essere davvero due oggetti.

One way is to extract the arguments into a new class, but that would surely lead to an explosion of classes?

Se il tuo modello di dominio ha molti diversi tipi di cose, allora il tuo codice finirà con molti diversi tipi di oggetti. Non c'è niente di sbagliato in questo.

And those classes are likely to end up with names that violate some of the naming rules (ending with "Data" or "Info" etc)?

Se non riesci a trovare un nome appropriato, forse hai raggruppato troppi argomenti insieme o troppo pochi. Quindi, hai solo un frammento di una classe o hai più di una classe.

Another technique is to make variables used by multiple functions a private member variable to avoid passing them, but that expands the scope of the variable, possibly such that it's open to functions that don't actually need it.

Se hai un gruppo di metodi che operano tutti sugli stessi argomenti e un altro gruppo di metodi che non lo fanno, forse appartengono a classi diverse.

Nota quante volte ho usato la parola "forse"? Ecco perché quelle sono linee guida, non regole. Forse il tuo metodo con 4 parametri è perfettamente adatto!

    
risposta data 23.09.2016 - 13:31
fonte
5

Nota che gli argomenti zero non implicano effetti collaterali, perché il tuo oggetto è un argomento implicito. Guarda quanti metodi zero-arity l'immutabile lista di Scala ha, per esempio.

Una tecnica utile che chiamo la tecnica della "messa a fuoco dell'obiettivo". Quando si mette a fuoco un obiettivo della fotocamera, è più facile vedere il vero punto di messa a fuoco se lo si prende troppo lontano, quindi lo si spegne nel punto corretto. Lo stesso vale per il software refactoring.

Specialmente se usi il controllo della versione distribuita, le modifiche al software sono facili da sperimentare, vedi se ti piace come sembrano e se non lo fai, ma per qualche motivo le persone sembrano riluttanti a farlo.

Nel contesto della tua domanda attuale, ciò significa scrivere le versioni zero o una argomento, con prima alcune funzioni di divisione, quindi è relativamente facile vedere quali funzioni devono essere combinate per la leggibilità.

Si noti che l'autore è anche un grande sostenitore dello sviluppo basato sui test, che tende a produrre funzioni di bassa aritmetica all'inizio, perché si inizia con i banali test case.

    
risposta data 23.09.2016 - 13:59
fonte
0

Un approccio che semplicemente (e ingenuamente - o dovrei anche dire ciecamente ) mira a ridurre il numero di argomenti a funzioni è probabilmente sbagliato. Non c'è assolutamente nulla di sbagliato in funzioni che hanno un numero elevato di argomenti. Se sono richiesti dalla logica, sono obbligatori ... Una lunga lista di parametri non mi preoccupa affatto - purché sia formattata correttamente e commentata per la leggibilità.

Nel caso in cui tutto o un sottoinsieme di argomenti appartengano a un'unica entità logica e siano comunemente passati in giro in gruppi in tutto il programma, è forse ha senso raggrupparli in qualche contenitore - Tipicamente un struct o altro oggetto. Esempi tipici possono essere una sorta di tipo di messaggio o evento .

Puoi facilmente esagerare con questo approccio: una volta scoperto che il riempimento e lo spacchettamento da e verso tali contenitori di trasporto genera un sovraccarico maggiore di quello che migliora la leggibilità, probabilmente sei andato troppo oltre.

OTOH, elenchi di parametri di grandi dimensioni possono essere un segno che il tuo programma potrebbe non essere strutturato correttamente - forse la funzione che richiede un numero così elevato di parametri sta solo cercando di fare troppo e dovrebbe essere divisa in diverse funzioni più piccole. Preferisco iniziare qui piuttosto che preoccuparmi di # dei parametri.

    
risposta data 23.09.2016 - 13:04
fonte
0

Non c'è un modo magico: devi padroneggiare il dominio del problema per scoprire la giusta architettura. Questo è l'unico modo per refactoring: padroneggiare il dominio del problema. Più di quattro parametri è solo una scommessa sicura che la tua attuale architettura sia errata e sbagliata.

Le uniche eccezioni sono i compilatori (metaprogrammi) e le simulazioni, in cui il limite è teoricamente 8, ma probabilmente solo 5.

    
risposta data 18.06.2018 - 17:33
fonte

Leggi altre domande sui tag