Aggiunta di informazioni qualitative ai nomi di funzioni

-2

Ho iniziato ad aggiungere informazioni sul comportamento delle funzioni al loro nome di recente.

Due grandi esempi:

  • pure - questa funzione non ha effetti collaterali (oltre al valore restituito), che userei in Java come static int addingNumbersPure(int a, int b) (cattivo esempio dato che nessuno si aspetterebbe effetti secondari in tale metodo, ma si ottiene la deriva).
  • linearTime - la complessità del runtime del grande-o del codice, ad esempio Object searchPureLogTime(Object[] sortedArray) .

Questo mi dà (e altri chiamano il mio codice) una visione più profonda di ciò che questi metodi fanno - utili in progetti più grandi - ma d'altra parte, non mi sento a mio agio nell'utilizzarlo nelle definizioni di interfaccia, poiché potrebbero essere estese con altre funzionalità, rompendo questo contratto. Quindi ovviamente lo uso solo per metodi che non sono progettati per essere estesi (tuttavia è implementato, tramite parole chiave della lingua o l'architettura del progetto stesso).

Un'alternativa che usavo prima era Javadocs (o qualunque altro sistema doc fosse usato in un progetto) per aggiungere quelle informazioni, ma non conosco alcun IDE che li incoraggi nell'editor corrente - quindi leggendo il codice come un blocco non dà al lettore quelle informazioni.

Alla fine, sono in conflitto. Il mio modo di aggiungere queste informazioni è migliore o peggiore rispetto a non dare queste informazioni? Esiste un modo migliore e più agevole di farlo? Qual è lo standard del settore?

PS: anche se questa domanda è indipendente dal linguaggio, è ovviamente irrilevante in linguaggi come Haskell, dove per esempio pure non è una nuova informazione.

    
posta Hard.At.Sleep 30.09.2017 - 11:12
fonte

3 risposte

7

Non mi piace. Entrambi i tuoi esempi hanno problemi.

Quando si tratta di Pure uno, l'annotazione dovrebbe essere leggibile principalmente dagli strumenti di analisi statica. Quelli possono controllare se è veramente puro e assicurarsi che sia chiamato correttamente. E non credo che molti strumenti usino il nome del metodo per questo. Ad esempio, C # ha PureAttribute per esattamente questo motivo.

In generale, lo scopo principale del nome del metodo è di dirmi, il client, che dovrei usare. Se hai un solo metodo con una singola complessità temporale, quale scelta ho? Avrebbe senso solo se avessi due metodi, ognuno facendo la stessa cosa, ma con una complessità diversa. Ma allora, perché avere un metodo con una complessità peggiore, in primo luogo? In quanto tale, sembra un rumore inutile.

Un altro problema di cui mi preoccupo è che aumenta il rischio di menzionare il nome della funzione. Questo succede quando cambi il funzionamento interno della funzione senza cambiare il nome. Ancora peggio, quando la funzione è pubblicata, dove non è possibile modificare il nome.

Un'altra domanda è quando dovrebbero essere usate quelle "annotazioni"? Ovviamente, non dovrebbe essere prima di ogni metodo, in quanto ciò creerebbe tonnellate di spese generali. Quindi diventa una battaglia ogni qual volta un metodo specifico dovrebbe o non dovrebbe avere l'annotazione.

tl; dr; Aggiungete davvero questa annotazione solo se esistono più metodi simili e tale annotazione mi fornirà, il cliente, informazioni critiche su quale sia il metodo giusto per il mio uso. E se tali informazioni non possono essere fornite attraverso la lingua o la funzionalità del framework. Altrimenti, la documentazione è abbondante nei casi in cui potrei essere interessato a tali informazioni.

    
risposta data 30.09.2017 - 11:45
fonte
3

Per estendere la risposta di @ Euphoric:

Cose come il runtime big-O non dovrebbero diventare parte del contratto, poiché la sostituzione dell'implementazione con un algoritmo più veloce interromperà il contratto esistente o creerà una nuova funzione con un nuovo contratto. E suppongo che tu non voglia nominare il tuo metodo searchPureAtMostNSquareTime(Object[] sortedArray) .

E se il tuo metodo richiede più di un parametro (ad esempio due elenchi), come esprimi le informazioni se è O (log (list1.size ())) o O (log (list2.size ()))? Finirai con nomi completamente illeggibili.

Arriviamo alla leggibilità del codice. Preferirei sicuramente leggere search(array) anziché searchPureLogTime(array) . Con quest'ultimo, devo analizzare mentalmente il nome e rimuovere i suffissi finché non trovo che è solo una chiamata di "ricerca".

Vedo sicuramente il beneficio delle informazioni che vuoi fornire, ma dovresti trovare un modo diverso di farlo, magari creare le tue annotazioni.

    
risposta data 30.09.2017 - 15:40
fonte
2

Sono d'accordo con le altre risposte, aggiungendo la complessità alla firma del metodo interrompe l'incapsulamento, poiché non è possibile modificare l'implementazione senza influenzare la firma del metodo (nel caso in cui il nuovo algoritmo migliori le prestazioni, ad esempio).

Tuttavia, penso che il caso pure sia più complicato. Penso che ciò corrisponda alle aspettative che la tua biblioteca sta fornendo. Se ne stai progettando uno, e ogni funzione è pura che dovrebbe essere riflessa nei documenti di progettazione. Per fare un esempio da un'altra lingua in ramda tutte le funzioni restituiscono copie e sono al curry, quindi la tua aspettativa per ogni chiamata dovrebbe essere la stessa, senza avere per includere queste informazioni nel nome del metodo.

Un altro esempio che potresti usare per l'ispirazione sarebbe il rubino. Lì, in certe situazioni, ci saranno due versioni di un metodo, uno con ! e uno senza. Ad esempio, sort restituisce una copia dell'array e sort! lo modifica in posizione. Nota che la convenzione non è usata in modo coerente, poiché esistono metodi distruttivi senza il botto, e metodi con un botto che non hanno a che fare con la "purezza" (come save e save! per ActiveRecord )

Nel caso di Java, credo che la pratica più accettata sarebbe quella di usare un'annotazione come Pure .

    
risposta data 30.09.2017 - 16:10
fonte

Leggi altre domande sui tag