Cómo y por qué decidir entre los métodos de nomenclatura con los prefijos "get" y "find"

48

Siempre tengo problemas para determinar si debo nombrar un cierto método comenzando con getSomethingversus findSomething.

El problema reside en crear ayudantes para API mal diseñadas. Esto generalmente ocurre cuando se obtienen datos de un objeto, que requiere el objeto como parámetro. Aquí hay un ejemplo simple:

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;
}

¿Cómo y por qué decidir entre nombrar este método como getRevision()o findRevision()?

conocidaasilya
fuente
2
la mejor ayuda para una API mal diseñada no es meterse con nombres complicados, sino establecer una Capa Anticorrupción : "Si su aplicación necesita tratar con una base de datos u otra aplicación cuyo modelo no es deseable o no es aplicable al modelo que desea dentro de su propia aplicación, use un AnticorruptionLayer para traducir a / desde ese modelo y el suyo ".
mosquito el
1
Nunca he oído hablar de este concepto antes. ¿Tienes mejores enlaces con ejemplos?
knownasilya
1
Busque en la web, hay mucha información sobre ella. Por ejemplo, Anatomía de una capa anticorrupción, Parte 1 "es probable que ... inevitablemente te enfrentes con la tarea de interactuar con los espaguetis que ya están allí. Entra en la capa anticorrupción ..."
mosquito

Respuestas:

83

Lo uso Getcuando sé que el tiempo de recuperación será muy corto (como en una búsqueda de una tabla hash o btree).

Findimplica un proceso de búsqueda o algoritmo computacional que requiere un período de tiempo "más largo" para ejecutarse (por algún valor arbitrario de más tiempo).

Robert Harvey
fuente
3
+1 Uso get al recuperar y encontrar cuándo se debe trabajar para obtener un get.
Jim
55
Teniendo en cuenta que el código cambia (algunas partes se optimizan y los algoritmos cambian) y cambiar la API a menudo es imposible, no parece un criterio correcto. ¿Qué harías si luego lo reemplazaras findcon un algoritmo de tabla hash?
meze
2
También supondría, al leer una llamada, que se puede llamar "buscar" cuando la búsqueda no tiene éxito porque el criterio de búsqueda no tiene éxito, mientras que se espera que "obtener" tenga éxito a menos que haya algún problema inusual.
gnasher729
¿Qué sucede si la función acepta un parámetro opcional para filtrar los resultados en función de alguna condición? Ambos gety findse aplicarían según cómo se use.
ESR
62

Yo diría que findpuede fallar pero getno debería.

volcado de memoria
fuente
25
Si quiere decir que findpuede devolver NULL mientras getque nunca devolverá NULL pero podría arrojar (o afirmar), estoy de acuerdo.
Sjoerd
1
Estoy totalmente de acuerdo con @Sjoerd en esto.
mhr
¿Y si las find()devoluciones Optional<>? En ese caso findtambién es nullseguro.
TheCoder
42

Para citar una conversación que a menudo tengo con mis hijos:

Yo: Hola chico! Ve a buscarme algunas baterías

niño: ¿ Pero dónde están?

Yo: Por eso te dije que fueras a buscarlos . Si supiera dónde están, te habría dicho que fueras a buscarlos . O podrías preguntarle a tu madre.

La misma idea es válida:

  • use "get" para un método que devuelva una información disponible a bajo precio (y que probablemente pueda ser incorporada o de otra forma optimizada), o para una información de propiedad exclusiva de este objeto.

  • use "find" para un método que funcione para obtener información, o use otros objetos para encontrarla.

jimwise
fuente
16
Solo un programador tendría esta conversación con sus hijos. "¿Quieres sacar la basura?" "No." "¿Sacarás la basura?" "Si."
Robert Harvey
@RobertHarvey Creo que estoy teniendo este problema con la gente. Cada vez que alguien intenta explicar algo, o hace una pregunta, generalmente hago preguntas y les digo que sean explícitos al respecto. De lo contrario, generalmente terminamos con un problema XY. Si no hago eso, me siento como una función de autocompletar caminando. No sabes lo que tienes en mente, no puedes ponerlo en palabras, balbuceas un par de palabras y esperas que yo haga todo el "pensamiento" por ti y te ayude con eso. No, no sucede :)
akinuri
3

Buscar implica no tener el resultado, como cuando se ejecuta una consulta de base de datos con algunos parámetros que pueden cambiar entre llamadas. Obtener, por otro lado, implica que los resultados son conocidos por el método de antemano o que no cambiarán una vez conocidos, que no hay parámetros para la llamada.
Entonces, usaría, por ejemplo, Customer findCustomerById (long customerId) y Customer getCustomer ()

jwenting
fuente
3

Aplico el siguiente patrón:

  • Foo GetFoo() no puede devolver nulo y su complejidad es O (log (n)) o menos
  • bool TryGetFoo(out Foo) puede devolver nulo y su complejidad es O (log (n)) o menos
  • Foo FindFoo() no puede devolver nulo y su complejidad es más que O (log (n))
  • bool TryFindFoo(out Foo) puede devolver nulo y su complejidad es más que O (log (n))

De esa manera, el código es bastante claro sobre la intención y la complejidad que puede esperar.

Por lo general, los Getters son para acceso directo a listas o diccionarios / conjuntos.
Los buscadores son búsqueda profunda, escaneo completo de la lista, etc.

En tu 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;
    }
}
Cyril Gandon
fuente
+1 para el try, corto y preciso
SpaceTrucker
2

getes apropiado en cualquier caso _ de hecho, a menudo se supone que para obtener algo, primero debe encontrarlo. Entonces, si no estás seguro, úsalo get.

Lo usaría findpara métodos como findMinimum()o findOptimal(), es decir, donde hay algún algoritmo especial que calcula el valor de retorno, y no simplemente hace una solicitud al DB, sistema de archivos, servidor remoto, etc. para recibir algunos datos.

superM
fuente
1
Buenos puntos. Personalmente, probablemente no lo usaría findcomo prefijo en los ejemplos que proporcionó. Para tareas computacionales, como las de su ejemplo, usaría calculateo compute.
conocidoasilya
2

No use buscar u obtener prefijos. Esto es una violación de UniformAccessPrinciple acuñado por bertrand meyer. ¿Por qué no crear un método como el siguiente?

public String revision(Item item)
giorgi dvalishvili
fuente
estoy completamente de acuerdo contigo, genial !!!!
Irakli Gabisonia
1

Generalmente lo usaré Getpara recuperar un objeto / valor, y Findpara recuperar su ubicación (en una matriz, por ejemplo).

por ejemplo:

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

integer i = somearray.Find( 'name');
Gran maestro B
fuente
0

Para mí, findimplica que posiblemente puede haber más de un resultado presente. getimplica solo uno.

Karl Bielefeldt
fuente
8
Parece que tiene esa sensación, pero no estoy seguro de estar completamente de acuerdo. Piénsalo de esta manera: getCatvs findCatvs getCatsvs findCats. El find..todavía representa objetos singulares que se devuelven. El plural debe agregarse al sustantivo, en mi opinión.
conocidoasilya