Legibilidad de nombres de métodos booleanos

120

Pregunta simple, desde el punto de vista de la legibilidad, qué nombre de método prefiere para un método booleano:

public boolean isUserExist(...)

o:

public boolean doesUserExist(...)

o:

public boolean userExists(...)
Yuval Adam
fuente
21
el primero suena comoisBabbyFormed
Depende del idioma. Los diferentes idiomas tienen diferentes convenciones; Me vienen a la mente Java y Objective C. También al límite de lo subjetivo.
Jed Smith
Subjetivo - bastante justo
Yuval Adam
2
Puramente subjetivo. getUserExistence, userIsNotExtinct, userHasExistentialStateEtc ...
dreamlax
Sartre estaría orgulloso
Cornel Masson

Respuestas:

112
public boolean userExists(...)

Sería mi preferido. Como hace que sus verificaciones condicionales se parezcan mucho más al inglés natural:

if userExists ...

Pero supongo que no hay una regla estricta y rápida, solo sé constante

Martín
fuente
3
"hace que tu {llamada al método} se parezca mucho más al inglés natural" suena como una gran prueba para la nomenclatura racional en todos los ámbitos. Aclaró mi pensamiento al respecto - ¡gracias!
Cori
16
Por otro lado, de forma aislada o cuando no está inmediatamente después de "if", entonces "userExists ()" suena como una declaración de hecho, en lugar de la pregunta que pretendía. A diferencia de "IsUserExisting ()" o "DoesUserExist ()", que sigue las reglas de orden de palabras del idioma natural en inglés para preguntas sencillas.
Oskar Berggren
4
... pero ¿por qué se utilizarían los métodos que devuelven un bool fuera de un if? Si tienen efectos secundarios, es aún más un olor. if IsUserExisting()y se if DoesUserExist()ve horrible y debe evitarse.
RJFalconer
@RJFalconer a veces puede que necesite usar el resultado de ese método en varios lugares, por lo que lo asignará a la variable. Dado que se llama al método userExists, ¿qué nombre de variable declarará? userExistses bueno para variables, no para métodos. Como escribió @Oskar, suena como una declaración, no una pregunta.
Jarosław Wlazło
Para situaciones en las que tiene que haber un sujeto, un predicado y un objeto, por ejemplo, UserSessionIsComplete o IsUserSessionComplete, ¿cuál prefiere?
Yang
40

Yo diría userExists, porque el 90% de las veces mi código de llamada se verá así:

if userExists(...) {
  ...
}

y se lee muy literalmente en inglés.

if isUserExisty if doesUserExistparecen redundantes.

Kai
fuente
18

Tenga cuidado con sacrificar la claridad mientras persigue la legibilidad .

Aunque se if (user.ExistsInDatabase(db))lee mejor que if (user.CheckExistsInDatabase(db)), considere el caso de una clase con un patrón de constructor (o cualquier clase en la que pueda establecer el estado):

user.WithName("Mike").ExistsInDatabase(db).ExistsInDatabase(db2).Build();

No está claro si ExistsInDatabaseestá comprobando si existe o estableciendo el hecho de que existe. No escribiría if (user.Age())o if (user.Name())sin ningún valor de comparación, entonces, ¿por qué es if (user.Exists())una buena idea simplemente porque esa propiedad / función es de tipo booleano y puede cambiar el nombre de la función / propiedad para que se lea más como inglés natural? ¿Es tan malo seguir el mismo patrón que usamos para otros tipos que no sean booleanos?

Con otros tipos, una ifdeclaración compara el valor de retorno de una función con un valor en el código, por lo que el código se parece a:

if (user.GetAge() >= 18) ...

Lo que dice "si el usuario dot get age es mayor o igual a 18 ..." cierto: no es "inglés natural", pero yo diría que object.verbnunca se asemeja al inglés natural y esto es simplemente una faceta básica de la programación moderna (por muchos idiomas convencionales). Los programadores generalmente no tienen problemas para entender la declaración anterior, entonces, ¿la siguiente es peor?

if (user.CheckExists() == true)

Que normalmente se abrevia a

if (user.CheckExists())

Seguido por el paso fatal

if (user.Exists())

Si bien se ha dicho que "el código se lee 10 veces más de lo que se escribe", también es muy importante que los errores sean fáciles de detectar. Suponga que tiene una función llamada Exists () que hace que el objeto exista y devuelve verdadero / falso según el éxito. Podría ver fácilmente el código if (user.Exists())y no detectar el error; el error sería mucho más obvio si el código se leyera, if (user.SetExists())por ejemplo.

Además, user.Exists () podría contener fácilmente código complejo o ineficiente, haciendo un viaje redondo a una base de datos para verificar algo. user.CheckExists () deja en claro que la función hace algo.

Vea también todas las respuestas aquí: Convenciones de nomenclatura: ¿Cómo nombrar un método que devuelve un booleano?

Como nota final, después de "Dile, no preguntes", muchas de las funciones que devuelven verdadero / falso desaparecen de todos modos, y en lugar de preguntarle a un objeto su estado, le dices que haga algo, que puede hacer en diferentes formas basadas en su estado.

Michael Parker
fuente
2
> Suppose you had a function called Exists() which causes the object to existEso ya es un problema. Tal método debería ser un verbo, como Create. Por lo menos lo sería Exist, pero "existir" como verbo rara vez se usa. It's not clear if ExistsInDatabase is checking whether it does exist, or setting the fact that it does exist.Es muy claro. Afirmaría que la mayoría de los desarrolladores se sorprenderían si eso hiciera algo más que devolver un booleano.
RJFalconer
@RJFalconer Most developerses la clave de tu oración allí. Yo diría all developersque me sorprendería si hiciera CheckExists()algo más que comprobar que algo existe. No es que Exists()sea ​​un nombre terrible, solo que CheckExists()es un nombre mejor , y esta pregunta es, como principio general, ¿cuál es el mejor patrón de nomenclatura? La respuesta es tratarla como cualquier otra función, comenzar el nombre con un verbo y no usar un patrón diferente solo porque devuelve un booleano.
Michael Parker
Sí, la pregunta es sobre el mejor patrón de nomenclatura PERO para los métodos booleanos. Los métodos bool son únicos y tienen su propio nombre común: predicado. No debe tratarlos como a otras funciones. Poner un verbo junto a la pregunta en el nombre del método booleano es redundante. Y tiene un impacto negativo en la legibilidad del código. Nombrar métodos booleanos en forma de preguntas, sin verbos, se acepta como la mejor práctica en la industria. Ejemplos: docs.microsoft.com/en-us/dotnet/api/system.io.file.exists developer.android.com/reference/java/io/File#exists ()
Almir
@Almir File.Exists es una llamada extremadamente antigua (al menos dot net 1.1) y no es un buen ejemplo de los estándares de legibilidad modernos. Mire la API moderna de dot net core para ver ejemplos más modernos de cómo Microsoft está de acuerdo: github.com/dotnet/sdk , algunos ejemplos aleatorios link link link
Michael Parker
15

El objetivo de la legibilidad siempre debe ser escribir código lo más parecido posible al lenguaje natural. Entonces, en este caso, userExistsparece la mejor opción. No obstante, el uso del prefijo "es" puede ser correcto en otras situaciones, por ejemplo isProcessingComplete.

Konamiman
fuente
1
Para su segundo ejemplo, ¿está ProcessingIsCompletemás cerca de los lenguajes naturales? Por ejemplo: if (ProcessingIsComplete ())
Yang
9

Yo iría con userExists () porque 1) tiene sentido en lenguaje natural y 2) sigue las convenciones de las API que he visto.

Para ver si tiene sentido en lenguaje natural, léalo en voz alta. "Si el usuario existe" suena más como una frase válida en inglés que "si el usuario existe" o "si el usuario existe". "Si el usuario existe" sería mejor, pero "el" probablemente sea superfluo en el nombre de un método.

Para ver si un archivo existe en Java SE 6, usaría File.exists () . Parece que será igual en la versión 7 . C # usa la misma convención , al igual que Python y Ruby . Con suerte, esta es una colección lo suficientemente diversa como para llamar a esto una respuesta independiente del idioma. En general, me pondría del lado de los métodos de nomenclatura de acuerdo con la API de su idioma.

David
fuente
5

Hay cosas a considerar que creo que se pasaron por alto en varias otras respuestas aquí.

  1. Depende si se trata de un método de clase C ++ o una función C. Si se trata de un método, es probable que se llame if (user.exists()) { ... }o if (user.isExisting()) { ... }
    no if (user_exists(&user)). Esta es la razón detrás de los estándares de codificación que indican que los métodos bool deben comenzar con un verbo, ya que se leerán como una oración cuando el objeto esté frente a ellos.

  2. Desafortunadamente, muchas funciones antiguas de C devuelven 0 para el éxito y no cero para el error, por lo que puede ser difícil determinar el estilo que se está utilizando a menos que siga todas las funciones bool que comienzan con verbos o siempre se comparan con verdadero como tal. if (true == user_exists(&user))

Lee Ballard
fuente
5

Mi regla simple para esta pregunta es esta:

Si el método booleano ya TIENE un verbo, no agregue uno. De lo contrario, considérelo. Algunos ejemplos:

$user->exists()
$user->loggedIn()
$user->isGuest() // "is" added
Jonathan
fuente
2

Puramente subjetivo.

Prefiero userExists(...)porque entonces declaraciones como esta se leen mejor:

if ( userExists( ... ) )

o

while ( userExists( ... ) )
zumalifeguard
fuente
1

En este caso particular, el primer ejemplo es un inglés tan horrible que me hace estremecer.

Probablemente optaría por el número tres debido a cómo suena al leerlo en declaraciones if. "Si el usuario existe" suena mejor que "Si el usuario existe".

Esto es asumiendo que se usará en pruebas de declaraciones if, por supuesto ...

Dana
fuente
1

Me gusta cualquiera de estos:

userExists(...)
isUserNameTaken(...)
User.exists(...)
User.lookup(...) != null
John Kugelman
fuente
0

Los nombres de los métodos sirven para facilitar la lectura, solo los que encajan en todo el código serían los mejores, ya que en la mayoría de los casos comienza con condiciones, por lo tanto, subjectPredicate sigue la estructura natural de la oración.

Yuan
fuente
0

¿Por qué no cambiar el nombre de la propiedad entonces?

if (user.isPresent()) {
Artem Lukanin
fuente