Come e perché decidere tra i metodi di denominazione con i prefissi "get" e "find"


48

Ho sempre difficoltà a capire se devo citare un certo metodo inizia con getSomethingrispetto findSomething.

Il problema risiede nella creazione di helper per API mal progettate. Questo di solito si verifica quando si ottengono dati da un oggetto, che richiede l'oggetto come parametro. Qui c'è un semplice esempio:

public String getRevision(Item item) {
    service.load(item, "revision");
    // there is usually more work to do before getting the data..
    try {
        return item.get_revision();
    }
    catch(NotLoadedException exception) {
        log.error("Property named 'property_name' was not loaded", exception);
    }
    return null;
}

Come e perché decidere tra denominazione questo metodo come getRevision()o findRevision()?


2
il miglior aiuto per un API mal progettato non è a pasticciare con denominazione difficile, ma stabilire un livello di Anticorruzione : "Se le vostre esigenze applicative per affrontare un database o un'altra applicazione il cui modello è indesiderabile o inapplicabili al modello che si desidera all'interno della propria applicazione, usa uno strato anticorruzione per tradurre da / verso quel modello e il tuo. "
moscerino del

1
Non ho mai sentito parlare di questo concetto prima. Hai collegamenti migliori con esempi?
knownasilya,

1
Cerca nel web, ci sono molte informazioni su di esso. Ad esempio, Anatomy of an Anti-Corruption Layer, Part 1 "è probabile che ... ti trovi inevitabilmente di fronte al compito di interagire con gli spaghetti che è già lì. Entra nello Anti-Corruption Layer ..."
gnat

Risposte:


83

Uso Getquando so che il tempo di recupero sarà molto breve (come in una ricerca da una tabella hash o btree).

Findimplica un processo di ricerca o un algoritmo computazionale che richiede un periodo di tempo "più lungo" per l'esecuzione (per un valore arbitrario di più lungo).


3
+1 Uso get durante il recupero e trovo quando è necessario eseguire il lavoro per ottenere un get.
Jim

5
Tenendo conto del fatto che il codice cambia (alcune parti vengono ottimizzate e gli algoritmi cambiano) e cambiare API è spesso impossibile non sembra un criterio giusto. Cosa faresti se in seguito venissi sostituito findcon un algoritmo hash-table?
Meze,

2
Suppongo anche, durante la lettura di una chiamata, che "find" possa essere chiamato quando la ricerca non riesce perché il criterio di ricerca non ha successo, mentre "get" dovrebbe avere successo a meno che non ci siano problemi insoliti.
gnasher729,

Cosa succede se la funzione accetta un parametro facoltativo per filtrare i risultati in base a una condizione? Entrambi gete findsi applicano a seconda di come viene utilizzato.
ESR,

62

Direi che findpotrebbe fallire ma getnon dovrebbe.


25
Se intendi che findpuò restituire NULL mentre getnon restituirà mai NULL ma potrebbe lanciare (o affermare), sono d'accordo.
Sjoerd,

1
Sono totalmente d'accordo con @Sjoerd su questo.
sig.

E se i find()ritorni Optional<>? In quel caso findè anche nullsicuro.
TheCoder

42

Per citare una conversazione che ho spesso con i miei figli:

io: Ehi ragazzo! Vai a cercarmi delle batterie

bambino: ma dove sono?

me: è per questo che ho detto di andare a trovare loro. Se avessi saputo dove fossero, ti avrei detto di andare a prenderli . Oppure potresti chiedere a tua madre.

La stessa idea vale:

  • usa "get" per un metodo che restituisce un'informazione a basso costo disponibile (e che probabilmente può essere incorporata o altrimenti ottimizzata) o per un'informazione posseduta in modo univoco da questo oggetto.

  • usa "trova" per un metodo che funziona per ottenere un'informazione o usa altri oggetti per trovarla.


16
Solo un programmatore avrebbe questa conversazione con i propri figli. "Vuoi portare fuori la spazzatura?" "No." "Tirerai fuori la spazzatura?" "Sì."
Robert Harvey,

@RobertHarvey Penso di avere questo problema con le persone. Ogni volta che qualcuno cerca di spiegare qualcosa o fa una domanda, di solito faccio domande e dico loro di essere esplicite al riguardo. Altrimenti di solito si finisce con un problema XY. Se non lo faccio, mi sento come una funzione di completamento automatico ambulante. Non sai cosa ti passa per la testa, non puoi dirlo in parole, chiacchieri parole di coppia e ti aspetti che io faccia tutto il "pensiero" per te e ti aiuti in questo? No, non sta succedendo :)
akinuri il

3

Trovare implica che non si ottengono risultati, ad esempio quando si esegue una query del database con alcuni parametri che possono cambiare tra le chiamate. Get, d'altra parte, implica che i risultati siano noti al metodo in anticipo o non cambieranno una volta noti, che non ci sono parametri per la chiamata.
Quindi, utilizzerei ad esempio Customer findCustomerById (long customerId) e Customer getCustomer ()


3

Applico il seguente modello:

  • Foo GetFoo() non può restituire null e la sua complessità è O (log (n)) o inferiore
  • bool TryGetFoo(out Foo) può restituire null e la sua complessità è O (log (n)) o inferiore
  • Foo FindFoo() non può restituire null e la sua complessità è maggiore di O (log (n))
  • bool TryFindFoo(out Foo) può restituire null e la sua complessità è maggiore di O (log (n))

In questo modo il codice è abbastanza chiaro sull'intento e sulla complessità che ci si può aspettare.

In genere, i Getter sono per l'elenco diretto o l'accesso a dizionario / set.
I Finder sono ricerca approfondita, scansione completa dell'elenco, ecc ...

Nel tuo caso:

public bool TryGetRevision( Item item, out String revision ) 
{
    service.load( item, "revision" );
    // there is usually more work to do before getting the data..
    try 
    {
        revision = item.get_revision();
        return true;
    }
    catch( NotLoadedException exception )
    {
        log.error( "Property named 'property_name' was not loaded", exception );
        revision = "";
        return false;
    }
}

+1 per il trybreve e preciso
SpaceTrucker

2

getè appropriato in ogni caso _ infatti si presume spesso che per ottenere qualcosa sia necessario prima trovarlo. Quindi, se non sei sicuro, usa get.

Vorrei utilizzare findmetodi come findMinimum()o findOptimal(), ad esempio, dove esiste un algoritmo speciale che calcola il valore restituito e non fa semplicemente una richiesta al DB, al file system, al server remoto, ecc. Per ricevere alcuni dati.


1
Punti buoni. Personalmente probabilmente non userei findcome prefisso negli esempi che hai fornito. Per compiti di calcolo, come quelli nel tuo esempio, vorrei usare calculateo compute.
knownasilya,


1

Generalmente userò Getper recuperare un oggetto / valore e Findper recuperare la sua posizione (in un array, ad esempio).

per esempio:

object o = obj.GetItem( 'name');

integer i = somearray.Find( 'name');

0

Per me, findimplica che potrebbe esserci più di un risultato presente. getimplica solo uno.


8
Sembra che abbia quella sensazione, ma non sono sicuro di essere completamente d'accordo. Pensate in questo modo: getCatvs findCatvs getCatsvs findCats. L' find..ancora rappresenta oggetti singolari restituiti. A mio avviso, il plurale dovrebbe essere aggiunto al nome.
knownasilya,
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.