Funzioni di denominazione che recuperano un valore

3

Ho questa regola personale per avviare tutti i nomi di funzioni / metodi con un verbo. Il mio verbo di scelta per funzioni o metodi che ottengono un valore basato su qualche struttura dati o oggetto è get . Mi chiedo se sia una buona idea.

Il bello di ottenere è che in realtà non dice nulla su in che modo viene recuperato quel valore, basta prenderlo. Qualcosa come calcolare (oltre ad essere terribilmente lungo) potrebbe essere troppe informazioni.

Questo vale per entrambe le funzioni e i metodi, cioè:

float get_magnitude(Vector2d vector)
{
    return sqrt(pow(vector.x, 2), pow(vector.y, 2));
}

o

float Vector2d::get_magnitude() const
{
    return sqrt(pow(x, 2), pow(y, 2));
}

D'altra parte, a volte finisco con i metodi getter per le proprietà di sola lettura. Potrebbe avere senso utilizzare un verbo più significativo per tutto ciò che non restituisce solo alcune proprietà e potrebbe non essere eseguito in un tempo lineare.

C'è un caso da fare per entrambi gli approcci o è solo una questione di gusti?

    
posta futlib 15.05.2013 - 08:28
fonte

6 risposte

9

La coerenza delle funzioni di denominazione è buona, ma puoi anche esagerare.

Se la funzione ogni che restituisce un valore si chiama getSomething , probabilmente lo stai esagerando. Il mio consiglio è di riservare il prefisso get per cose che sono concettualmente proprietà dell'oggetto su cui la funzione funziona, anche se il valore non è memorizzato esplicitamente nell'oggetto (come get_magnitude nell'esempio).

Se restituire un valore non è l'aspetto più importante della funzione, ma solo un effetto collaterale del vero scopo o design della funzione, allora chiamerei la funzione dopo quello che fa. Ad esempio, non c'è modo che io possa dare alla funzione fopen di C un prefisso get , anche se la funzione restituisce un valore importante (un handle per il file appena aperto).

    
risposta data 15.05.2013 - 10:11
fonte
5

La costante definizione dei nomi è buona, quindi "get_thingy ()" è buono, ma non vedo che leggere solo contro mutevole fa la differenza qui perché stai solo "leggendo" il valore.

Mi piace "di" come suffisso id devi passare un parametro come in "get_square_of (3)", e, se sai che c'è un lotto più coinvolto di un semplice recupero o calcolo quindi forse un altro verbo come "ottenere" può essere usato per indicare questo come in "get_meaning_of_life ()", anche alcune persone preferiscono "retrieve_" per indicare che il metodo implica una sorta di I / O o interazione esterna.

    
risposta data 15.05.2013 - 09:36
fonte
1

Hmmm ... Beh, è quasi sempre una preferenza personale, no? In generale, penso che le convenzioni di denominazione dovrebbero essere tali che non solo io capisco cosa sta succedendo nel mio codice sorgente, ma anche chiunque altro trovi il mio codice. Inoltre, tendo ad essere un minimalista nella documentazione del codice; a meno che non stia facendo qualcosa di molto difficile, il mio codice dovrebbe essere abbastanza intelligente da spiegarmi da solo anche se lo vedo a 3 anni da quando l'ho scritto in uno stupore da ubriaco. Quindi la coerenza tra i tuoi progetti, anche per la sanità interna, è importante.

Per esempio, quando uso i sistemi C su * nix, invariabilmente uso 0 come numeri positivi e negativi per segnalare errori; con l'eccezione sulle funzioni I / O dove return è size_t; quindi il numero positivo è la quantità di I / O; 0 è un arresto su I / 0 e (size_t) -1 è un errore con errno impostato su un errore di sistema; questo è coerente con il comportamento della libreria C sui sistemi, quindi so che tutti capiranno cosa sta succedendo.

Quando scrivevo programmi in Win32 usando C la convenzione di Win32 era un po 'diversa e ho seguito quella convenzione. Lì, i nomi usano camelCase in C (che è fastidioso per me ma lo seguo) e uso la notazione ungherese (che è ancora più fastidiosa), ma mi limito ad usarlo.

Tuttavia, se dovessi scrivere codice equivalente in C ++, cambierei il modo in cui riporto gli errori. Lanciare eccezioni o usare valori di ritorno booleani per metodi più semplici.

Se sono in modalità di programmazione del kernel, uso le convenzioni usate dagli sviluppatori del kernel;

Immagino che non voglio passare il tempo a spiegare il mio codice agli altri (che include me da 3 a 5 anni perché mi sarei cambiato) quindi uso il dialetto che capiranno da soli piuttosto che devo spiegare a loro la mia logica (in realtà non sono così intelligenti, e sono più stupido entro l'anno).

Penso che qualunque cosa tu usi, mantienilo coerente lungo un percorso logico che può sopravvivere attraverso linguaggi, attraverso i sistemi e la tua crescita tra adesso e tra 10 anni.

    
risposta data 15.05.2013 - 10:34
fonte
0

Per i metodi volti a recuperare un valore, alcune persone semplicemente omettono il verbo, considerando che questo è solo un accesso a una proprietà:

float Celsius() { return self.celsius; }

float Fahrenheit() { return self.celsius * 9.0/5.0 + 32.0; }
    
risposta data 15.05.2013 - 09:34
fonte
0

A seconda della lingua in cui lavori, getThingy o get_thingy potrebbero essere superflui.

Considera una tipica classe C ++ / Java / C # con un gruppo di getter e setter che sono solo degli accessor ai membri privati, il che è qualcosa che nel bene o nel male, un sacco di vedere ogni giorno.

Qual è la differenza tra getCustomerId () e customerId ()? Direi che non c'è molta differenza, perché sappiamo perfettamente che entrambi stanno recuperando un membro. Ma quest'ultimo ha una serie di vantaggi pragmatici:

    La convenzione
  • getCustomerId () ti costringerà a digitare più volte al giorno.
  • se hai la funzione di completamento automatico, non eseguirà un significativo kick in finché non digiti getC *, mentre in quest'ultimo caso kickerà dopo la prima lettera. Le mie dita fanno già male, e mi stai costringendo a continuare a raggiungere il tasto Maiusc per tutto il giorno (o il trattino basso per get_thingy)? Non bello.
  • Si perde il significativo 'get'. Ciò che intendo è che se la mia convenzione per l'accessor fosse customerId () e all'improvviso vedrei una funzione chiamata getCusomterId (), capirò che forse fa di più, come andare su un database forse, o iteratre qualche lista ? In assenza di ottenere le persone sono costretti a usare i verbi che sono quasi sinonimi, e poiché sono sinonimi questo crea confusione.

Mi piacerebbe chiudere con il seguente: dovremmo sempre usare la quantità minima di qualsiasi cosa necessaria per portarci dove vogliamo essere. L'efficienza è la chiave per fare le cose in modo intelligente. La regola di 'avere sempre un verbo in una funzione' è uno di quei mantra che semplicemente non passa quel test imho. Personalmente, do la colpa all'auto-generazione di setter e getter di Eclipse per lo status quo.

Persone, per favore lascia ottenere s superfluo dal tuo codice. In realtà non significano nulla.

    
risposta data 15.05.2013 - 17:57
fonte
0

Questa è una grande domanda, mi sto occupando di problemi simili adesso! A questo punto sto cercando di imparare le tecniche di codice pulito per la denominazione - i metodi dovrebbero essere nominati abbastanza bene da rendere inutili i commenti.

Tuttavia c'è più di un ottimo modo per nominare qualcosa. Così ora sto guardando un'applicazione funzionante con un sacco di classi e nomi chiari. Ma non sono completamente coerenti e ciò renderebbe l'app più chiara.

Ho utilizzato ottieni molto di recente. Per me ha solo 3 lettere, ha un bell'aspetto in caso di cammello e rende chiaro ciò che sta accadendo. non c'è alcuna ambiguità con getProductBy ($ id). Anche per me con get - c'è un indizio importante che potrebbe non ottenere il risultato . Potrebbe esserci un errore nel database, ecc. Ecc.

Quindi getProductBy ($ id) invia anche un avvertimento al flusso dell'applicazione - cercheremo di ottenere un prodotto per id, E potrebbe fallire quindi ci deve essere il controllo degli errori per qualsiasi cosa accada dopo.

    
risposta data 15.05.2013 - 21:51
fonte

Leggi altre domande sui tag