È una cattiva idea elencare ogni argomento di funzione / metodo su una nuova riga e perché?


22

Lavoro con qualcuno che, ogni volta che chiama una funzione, mette gli argomenti su una nuova riga, ad es

aFunction(
    byte1,
    short1,
    int1, 
    int2,
    int3,
    int4,
    int5
) ;

Lo trovo molto fastidioso in quanto significa che il codice non è molto compatto, quindi devo scansionare su e giù di più per dare un senso alla logica. Sono interessato a sapere se questa è in realtà una cattiva pratica e, in tal caso, come posso convincerli a non farlo?


25
+1, non so abbastanza per rispondere alla tua domanda, ma odio anche questo. Se hai così tanti argomenti in una funzione, allora probabilmente la tua funzione sta facendo troppo.
maple_shaft

28
Più precisamente, perché dobbiamo ancora vedere le altre preferenze su questo? perché i nostri IDE non possono presentarlo automaticamente nello stile che vogliamo?
Alex Feinman,

5
Mike, mi piace che il codice occupi spazio minimo sullo schermo. Ma è un compromesso. Ho messo {su una riga separata perché semplifica l'abbinamento con la chiusura} e la comprensione corretta dell'ambito del blocco. Vale la pena il compromesso di perdere una linea di proprietà dello schermo.
Brian Schroth,

2
@Alex: hai perfettamente ragione. Penso che la cosa giusta da fare sarebbe avere una lingua in cui l'albero di analisi del codice sia archiviato su disco e visualizzato in base alle preferenze dell'utente.
Neil G,

1
@maple_shaft Disprezzo affermazioni del genere. Non perché non ci sia alcuna verità, ma perché troppe persone seguono tali consigli senza lasciare spazio alle sfumature.
Stijn,

Risposte:


38

È solo una linea guida per la codifica che potrebbe piacerti o meno. L'importante è che tu e i tuoi colleghi decidiate di usarlo o meno.

Ovviamente, il modo migliore per aumentare la leggibilità è limitare il numero di argomenti.


24
Troppe persone riducono gli argomenti scaricandoli in un array. Preferirei vedere un brutto pasticcio piuttosto che un codice dall'aspetto più pulito con complessità nascosta.
Satanicpuppy,

18
Le matrici non sono la strada da percorrere. Potrebbe esserci una struttura nascosta negli arg, o forse la funzione sta facendo troppo e dovrebbe essere suddivisa.
Michael K,

4
Trovo che l'uso di più righe aiuti a rendere leggibile il codice SE i parametri sono espressione lunga o pochi. Altrimenti è solo fastidioso.
PedroC88,

3
Metterli in un oggetto di trasferimento dati sposta semplicemente il problema. Se sono richiesti tutti gli argomenti, devono essere tutti argomenti obbligatori del costruttore del DTO, il che significa che hai ancora tanti argomenti.
Scott Whitlock,

21

È una questione di preferenza. Per chiamate di funzioni complesse in cui si desidera documentare ciascun parametro o in cui le variabili sono piuttosto lunghe e ce ne sono molte, può essere utile.

Per esempio:

do_complex_op(
      0, //Starting state, always 0, ask Joe why
      X, //X-coord of thingy
      y, //Y-coord of thingy
      73, //in this case, we don't want to use Z but want constant 
      dlogMessageTitle, //message for dialogue title
      dlogMessageText, //message for dialogue contents, don't care about this.
      SomethingIP, //IP of something-or-other server, can be NULL, won't crash.
      someObject.childObject.getValue(key1).HVAL, //very long path to HVAL
      someObject.childObject.getValue(key1).LVAL, //very long path to LVAL
      this.parentWindow.owner.mainTextBox.text.value.trim, //get the trimmed text, untrimmed text causes weird output
      pvrMainSettingForLongBlahs.getObjectByPath(somePath),
      pvrMainSettingForLongBlahs.K_TCA_UPPER_LIMIT,
      pvrMainSettingForLongBlahs.K_ENDPOINT_COMPLIANCE_LEVEL,
 );

Con le lingue che consentono i parametri denominati questo è più comune se si utilizzano i nomi dei parametri (l'esempio è in PL / SQL):

PKG_SOME_TEST_CODE.FN_DO_SOMETHING( in_text => 'test text',
                                    in_id => v_id,
                                    in_ref_id => v_ref_id,
                                    out_array_for_storage => v_bArray); 

Ma sono d'accordo con te sul fatto che se la chiamata di funzione è semplice e non ci sono troppi parametri, questo potrebbe diventare fastidioso, come:

setColour (
    r,
    g,
    b
 );

Trovo molto più facile da leggere come

 setColour(r,g,b);

Per @ammoQ:

rc=a(b,c(d,e(f)))

rc=a(
     b,
     c(
       d,
       e(
         f
        )
      )
    )

11
Il primo esempio è una risposta errata a un problema reale. Perché non usare prima gli argomenti con variabili esplicite?
deadalnix,

@deadalnix: buon punto, ripulito un po '.
FrustratedWithFormsDesigner,

1
Vero. Tuttavia, non è sempre un problema con i nomi delle variabili. Ha più a che fare con nomi di variabili lunghe, argomenti con valori predefiniti, ecc.
inspectorG4dget

4
Direi che la soluzione migliore al problema è refactoring do_complex_op (), quindi prende una struttura come parametro. Quindi puoi farlo do_complex_op(new paramStruct { StartingState = 0, XCoord = xcoord }), quindi diventa auto-documentazione e molto più facile da leggere
KallDrexx

1
@KallDrexx: sono d'accordo, ma a volte cambiare il codice non è un'opzione, come quando è una funzione nella libreria di qualcun altro. Certo, potrei farne un wrapper, ma dovrò ancora chiamare la loro funzione originale ad un certo punto.
FrustratedWithFormsDesigner,

10

IMO tutto ciò che è insolito è una cattiva pratica a meno che non sia possibile dimostrare positivamente la superiorità rispetto al solito stile. "Matter of taste" è una scusa per scrivere codice che è più difficile da leggere del necessario per la maggior parte dei programmatori, perché un giorno un'anima povera, non abituata a quello stile, dovrà mantenere quel codice.

Dimostrare che non è comune è relativamente semplice, mostrare la fonte di esempi in MSDN o siti simili, mostrare basi di codice open source di grandi dimensioni, ecc. Mostrare l'output degli abbellitori di codice. Alla fine, mostra come lo sta facendo chiunque altro nella tua squadra. Non accettare uno stile cattivo solo perché qualcuno è troppo testardo.


Hm ... con questo approccio, come potremmo mai introdurre una nuova migliore pratica (o, grammaticamente corretta: una migliore pratica )?
Treb,

2
Treb: Certo, mostra solo che la pratica migliore è in effetti migliore , non solo diversa .
user281377

4
Ma "più difficile da leggere" è, di per sé, soggettivo e una questione di opinione. Per me, un argomento per riga è più facile da analizzare visivamente rispetto a due, tre o quattro argomenti per riga. E interrompo sempre una chiamata su più linee se si estende oltre il segno di 100 caratteri nell'editor.
Toby,

2
Meh. "Più difficile da leggere" può essere misurato oggettivamente. Tende solo a non esserlo. Discutere è più divertente.
JasonTrue,

1
può essere misurato oggettivamente ma non indipendentemente dalla persona che sta leggendo.
jk.

9

Bene, ecco qualche esca negativa. Non sono mai stato accusato di fare la cosa popolare. Chiaramente, se le cose si adattano su una linea, allora bene, adattale su una linea.

Ma la mia preoccupazione principale non è se il codice sia "brutto" o "carino". La mia preoccupazione principale è quanto sia facile capire e apportare modifiche senza commettere errori.

Se gli argomenti sono lunghi e ce ne sono molti, perché non metterli su righe separate? A mio avviso, ciò rende più facile vedere cosa sono e più facilmente modificarli se necessario. Mi dà anche spazio per allegare un commento a ogni argomento, se lo desidero.

Voglio anche ridurre al minimo la possibilità di commettere un errore se aggiungo o rimuovo un argomento a una funzione, che è più probabile che accada alla fine di un elenco di argomenti rispetto all'inizio. Per questo motivo, preferisco mettere la virgola (,) all'inizio di una riga, piuttosto che alla fine. Quindi, se per esempio, desidero rimuovere o aggiungere un argomento alla fine dell'elenco, è una modifica di una riga. Non devo andare a giocherellare con la virgola che deve andare alla fine di tutte le righe ma all'ultima, dove l'ultima deve finire con una parentesi.

Quindi (ragazzo, mi infiammerò per questo) lo scrivo così:

nameOfFunction(firstArgument
    , secondArgument // optional comment
       ...
    , lastArgument   // optional comment
    );

Quando c'è una funzione con da cinque a venti argomenti, la funzione non è stata così in una sola volta. È cresciuto nel tempo, il che significa che ci sono state molte modifiche. Qualsiasi modifica non completata è un errore di sintassi o un bug. Quindi non pretendo che sia carino. Affermo che aiuta a ottenere le modifiche giuste.

(E per quelli che dicono che dovrei passare una struttura, tutto ciò che fa è spostare il problema, perché hai bisogno di un sacco di righe di codice per riempire la struttura, per non parlare del codice aggiuntivo per dichiararlo e assegnarlo.)


1
Personalmente penso che questa sia un'ottima risposta perché hai spiegato molto bene il tuo ragionamento. Ottimo lavoro Mike.
Giordania,

8

Non lo definirei neanche io. La migliore pratica in cui ho lavorato è stata quella di avere tutte le chiamate di funzione su una sola linea, a meno che non si debba scorrere in orizzontale qualsiasi importo significativo per vedere l'intera chiamata. È un appello di giudizio, ma direi sicuramente che mettere tutte le funzioni in questo modo è fuori linea a meno che non sia lo standard stabilito dalla propria organizzazione.

Questo è il motivo per cui è buona prassi per un'organizzazione stabilire una serie di guide alle quali tutti i programmatori dovrebbero aderire. Si tratta di coerenza e leggibilità.


5

Semplifica:

  • Riordina argomenti.
  • Commenta o disabilita gli argomenti.
  • Vedi esattamente quale argomento è cambiato quando visualizzi le differenze nel tuo sistema di controllo della versione
  • Evita di rientrare nel rientro e di racchiudere le parole quando aggiungi o rimuovi un argomento o cambi il nome della funzione. (Anche se il tuo editor rientra automaticamente, stai comunque creando molte modifiche inutili agli spazi bianchi che rendono più difficile seguire le modifiche nel tuo sistema di controllo della versione.)

4

Direi che le chiamate di funzione dovrebbero essere tutte su una riga a meno che non superino in modo significativo la larghezza del codice standard (spesso 80 caratteri, spesso una causa di argomenti :-).

Non vedo alcun vantaggio in questo stile. Sembra soggettivamente brutto e lo trovo un dolore durante la ricerca del codice. Ad esempio, potresti voler cercare rapidamente e vedere se la funzione è mai stata chiamata con un determinato parametro passato come NULL. Questo è facile visivamente quando tutti i parametri sono su una riga e più difficile quando sono divisi in questo modo.


Questa cosa di 80 personaggi deve andare, non ci sono più ragioni tecnicamente valide per questo. Ora viviamo in un'era di monitor 19xx X 16xx e caratteri regolabili E dimensioni dei caratteri.
anon

4
@anon: validi motivi per questo? Perché pensi che il testo sia stampato in colonne e i libri siano più stretti di quanto potrebbero essere? Perché l'occhio umano perde traccia quando legge su righe molto lunghe.
Zan Lynx,

4
@anon: Mi piace anche usare il mio widescreen per avere due o tre file aperti in una divisione orizzontale che torna a 80-100 caratteri in una riga.
Zan Lynx,

4
@anon: Tecnicamente no, praticamente: inferno SÌ. Zan Lynx ha perfettamente ragione, inoltre ci sono ulteriori motivi: fusione, diff, utilizzo delle utility da riga di comando ... Oh e buona fortuna concentrandoti sul carattere 8p man mano che invecchierai: o)
MaR

3

Ho spesso visto quello stile su dichiarazioni o definizioni di funzioni , ma mai su una chiamata (fino ad ora). Lì a volte ha senso in quanto consente di aggiungere un commento per i singoli parametri in modo più chiaro. Sembra che abbia copiato quello stile in chiamate senza conoscere veramente le ragioni sottostanti. Hai una buona argomentazione contro e non sembra che ne abbia una buona, quindi hai il mio voto, ma non sono io quello che devi convincere.


Vedo entrambe le chiamate. Se l'elenco dei parametri è troppo lungo, dovrebbe essere suddiviso su più righe. Se i parametri non si raggruppano normalmente entro limiti di larghezza, mi aspetto che siano su linee separate. Se i nomi delle funzioni e dei parametri si adattano bene su una riga, spesso li vedo disposti in questo modo.
BillThor,

2

È contrario agli standard di codifica dell'azienda?

In caso contrario, avvia una discussione sugli standard e su cosa le persone vorrebbero vedere cambiate. Assicurati di presentarlo come una delle cose che vorresti cambiare.

Discuti a fondo sul perché non ritieni che ciò sia utile e spero che vincerai la giornata. Non sai mai che il tuo collega potrebbe convincerti che la sua strada è la migliore dopo tutto;)

Una volta che hai uno standard aggiornato, è documentato ciò a cui tutti dovrebbero codificare, quindi se il tuo collega persiste nel farlo, puoi aumentarlo nelle sue revisioni del codice.


2

Può sembrare strano, ma semplifica il lavoro sul codice. Durante il refactoring puoi commentare i singoli argomenti molto facilmente e controllare il tuo refactor prima di eliminare effettivamente le cose. Puoi anche commentare e sostituire temporaneamente i tipi abbastanza facilmente.

È anche più facile da leggere rispetto a:

int f(int, int, int,
      char, double, int
      X const&, Y)
{}

Non sono andato così estremo come stai mostrando (dal momento che non ci sono nomi sui parametri non è molto utile), ma ho preso l'abitudine di dividere ogni parametro sulla sua stessa linea o di non fare alcuna divisione.

La parte importante è che il tuo codice può essere stampato o visualizzato su display standard da 80col ed essere comunque leggibile.


2

Raramente otterrai una risposta onesta da un programmatore per qualcosa del genere. Tutti risponderanno semplicemente con ciò che fanno o non preferiscono. La verità è che, per quanto tutti noi lottiamo con essa a volte, l'unica "cattiva pratica" qui è la tua inflessibilità.

Devi essere brutalmente onesto con te stesso per essere in grado di distinguere tra cose che sono effettivamente cattive e cose che ti infastidiscono. La verità è che in C / C ++ e linguaggi simili raramente troverai una pratica di rientro che ha un effetto tangibile sulla comprensibilità del codice. La maggior parte delle discussioni su questo genere di cose ha solo le parti in comune con persone che fanno argomentazioni ridicole e disingenue per cercare di giustificare le proprie preferenze personali.

Quale alla mia lettura ... è esattamente quello che mi stai chiedendo in questa domanda: un argomento ridicolo e disingenuo per giustificare le tue preferenze personali.


0

A dire il vero dipende dalla persona .. Direi per funzioni complesse come dimostrato dal primo esempio di FrustratedWithForms, quindi sì; altrimenti un grande NO. Quindi di nuovo questo è il motivo per cui preferisco applicare arbitrariamente la funzionalità IDE del codice.


0

"Sono interessato a sapere se questa è in realtà una cattiva pratica ..."

Sì, è una cattiva pratica, tranne quando l'elenco delle variabili è insolitamente lungo. Ma in quel caso, il problema è probabilmente dovuto al design della funzione. Perché non passare un oggetto che incapsula molti parametri?

"... e se sì, come posso convincerli a non farlo?"

Legali e continua a solleticare finché non accettano di fermare quella merda.


"Perché non passare un oggetto che incapsula molti dei parametri?" OK, ora hai spostato il problema su quel nuovo oggetto. Ha ancora bisogno della stessa quantità di parametri (tramite il suo costruttore, ad esempio), quindi hai ancora lo stesso problema.
Stijn,

-2

Perché stai sprecando cicli su una preoccupazione così banale? Basta accendere il tuo IDE fidato, aprire il file e riformattare. Ecco! Sarà in qualunque forma tu voglia.

Passiamo ora alla questione davvero importante: vi o emacs, LOL.


E poi quando vieni a controllarlo nel controllo del codice sorgente?
pdr

-2

Direi che se gli argomenti si adattano su una riga, fallo. In caso contrario, un argomento per riga garantisce un'ottima leggibilità.

foo(arg1, arg2, arg3, arg4, arg5)

vs.

foo(
    arg1=arg1,
    arg2=arg2,
    arg3=arg3,
    arg4=arg4,
    arg5=arg5,
    arg6=arg6,
    arg7=arg7
)

3
questo non sembra offrire nulla di sostanziale rispetto ai punti formulati e spiegati nelle precedenti 14 risposte
moscerino del
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.