Si hay un método
bool DoStuff() {
try {
// doing stuff...
return true;
}
catch (SomeSpecificException ex) {
return false;
}
}
¿debería ser llamado IsStuffDone()
?
El usuario puede malinterpretar ambos nombres: si el nombre es DoStuff()
por qué devuelve un valor booleano? Si el nombre es, IsStuffDone()
no está claro si el método realiza una tarea o solo verifica su resultado.
¿Hay alguna convención para este caso? ¿O un enfoque alternativo, ya que este se considera defectuoso? Por ejemplo, en lenguajes que tienen parámetros de salida, como C #, una variable de estado booleana podría pasarse al método como uno y el tipo de retorno del método sería void
.
EDITAR: en mi problema particular, el manejo de excepciones no se puede delegar directamente a la persona que llama, porque el método es parte de una implementación de interfaz. Por lo tanto, la persona que llama no puede ser acusada de ocuparse de todas las excepciones de diferentes implementaciones. No está familiarizado con esas excepciones. Sin embargo, la persona que llama puede lidiar con una excepción personalizada StuffHasNotBeenDoneForSomeReasonException
como se sugirió en la respuesta y comentario de npinti .
fuente
boolean
lugar de envolver o pasar la excepción es casi siempre incorrecto.BadlyDesignedMethodInSeriousNeedOfRefactoring
? Y para responder a su pregunta sobre las excepciones, dejaría que la persona que llama las maneje o las atrape y luego arroje una excepción personalizada que significa "este método no hace su trabajo". Comparte y Disfruta.if (FirstMethodSucceeds(problem) or SecondMethodSucceeds(problem) or ...) Hurray(); else UniversalSolve(problem);
. Hacer lo mismo con excepciones (¿personalizadas?) Sería inútilmente más complicado.Respuestas:
En .NET, a menudo tiene pares de métodos donde uno de ellos puede lanzar una excepción (
DoStuff
), y el otro devuelve un estado booleano y, en una ejecución exitosa, el resultado real a través de un parámetro de salida (TryDoStuff
).(Microsoft llama a esto el "Patrón Try-Parse" , ya que quizás el ejemplo más destacado para ello son los
TryParse
métodos de varios tipos primitivos).Si el
Try
prefijo es poco común en su idioma, entonces probablemente no debería usarlo.fuente
if (TryDoStuff()) print("Did stuff"); else print("Could not do stuff");
Es un lenguaje bastante estándar e intuitivo en mi opinión.TryDoStuff
se supone que los métodos fallan limpiamente y no tienen efectos secundarios cuando devuelven falso.Remove
métodos, por ejemplo, en .NET Framework que eliminarán un elemento de una estructura de datos (por ejemploDictionary
) y devolverán abool
. El consumidor de la API puede decidir consumirlo o ignorarlo. Sin embargo, los errores se informan como excepciones.¿Qué pasa si simplemente lanzaste la excepción al código de llamada?
De esta manera, está delegando el manejo de excepciones a quien esté usando su código. ¿Qué pasa si en el futuro desea hacer lo siguiente?
FileNotFoundException
se lanza a, tome la acción BSi rechaza su excepción, el cambio anterior simplemente implicaría la adición de un
catch
bloque adicional . Si lo deja como está, necesitaría cambiar el método y el lugar desde el que se llama el método, que, dependiendo de la complejidad del proyecto, puede estar en múltiples ubicaciones.fuente
DoStuff
que falle, lanzar una excepción para el caso de falla sería similar a controlar el flujo del programa con excepciones que son malas. Las excepciones también tienen un costo de rendimiento inherente. SiDoStuff
fallar es un caso poco común debido a un error, entonces definitivamente las excepciones son el camino a seguir, como sugiere @npinti.DoStuff()
método de OP se limpia después de que el código interno arroje una excepción, y las condiciones posteriores del método siguen siendo correctas, un código de retorno puede ser una mejor opción ya que el error se ha manejado.DoStuff()
es suficiente, y el valor de retorno de la función debe documentarse, y no necesita mencionarlo en el nombre de la función, buscando muchas API disponibles:PHP
C-Sharp
fuente
En Java, la API de colección define un método de agregar que devuelve un valor booleano. Básicamente, devuelve si el complemento cambió la colección. Entonces, para un
List
, generalmente devolverá verdadero, ya que el elemento se agregó, mientras que para unSet
podría devolver falso, si el elemento ya estaba allí, ya queSet
s permite cada elemento único como máximo una vez.Dicho esto, si agrega un elemento que no está permitido por la colección, por ejemplo, un valor nulo, el complemento arrojará un valor
NullPointerException
falso en lugar de devolverlo.Cuando aplica la misma lógica a su caso, ¿por qué necesita devolver un valor booleano? Si es para ocultar una excepción, no lo hagas. Solo lanza la excepción. De esa manera puedes ver lo que salió mal. Si necesita un valor booleano, ya que podría no haberse hecho, por alguna otra razón que no sea una excepción, asigne un nombre al método
DoStuff()
, ya que representa el comportamiento. Hace cosasfuente
Podría fallar por diferentes razones, excepción, condiciones normales, así que usaría esto:
Importante es documentar lo que significa el booleano.
fuente
Por lo general, los métodos devuelven un
OperationResult
(oOperationResult<T>
) y establecen laIsSuccess
propiedad en elOperationResult
apropiado. Si el método 'usual' es nulo, devuelvaOperationResult
, si el método 'usual' devuelve un objeto, devuelvaOperationResult<T>
y establezca laItem
propiedad en elOperationResult
apropiado. También sugeriría tener métodos enOperationResult
como.Failed(string reason)
y.Succeeded(T item)
.OperationResult
rápidamente se convierte en un tipo familiar en sus sistemas y los desarrolladores saben cómo manejarlo.fuente
Realmente depende del idioma que estés usando. Al igual que para algunos idiomas, existen convenciones y protocolos que realmente no existen en muchos idiomas o en ninguno.
Por ejemplo, en el lenguaje Objective-C y los nombres de métodos SDK de iOS / Mac OS X generalmente van en la línea de:
Como puede ver, hay un método llamado viewDidLoad. Prefiero usar este tipo de nombres cada vez que hago mis propias aplicaciones. Esto podría usarse para verificar si se suponía que algo iba a suceder como usted dijo. Creo que estás pensando demasiado en lo que nombras tus métodos. La mayoría de los métodos devuelven el estado de lo que hacen independientemente, tome el ejemplo:
En PHP, mysql_connect () devolverá falso si la conexión falla. No dice que lo hará, pero lo hace y la documentación dice que sí, por lo que no se puede malinterpretar al programador.
fuente
Me gustaría sugerir utilizar el prefijo 'Probar'. Este es un patrón bien conocido para situaciones en las que el método puede tener éxito o no. Este patrón de nombres ha sido utilizado por Microsoft en .NET Framework (por ejemplo, TryParseInt).
Pero, tal vez no se trata de nombrar. Se trata de cómo diseñar los parámetros de entrada / salida de su método.
Mi idea es que si un método tiene un valor de retorno, entonces el propósito de llamar a ese método debería ser obtener ese valor de retorno. Por lo tanto, debe evitar usar el tipo de retorno para indicar el estado de una operación.
En C #, prefiero usar un parámetro out. Usando una salida, estoy marcando el parámetro como un parámetro lateral. Especialmente que C # 6 admitirá la declaración de variable en línea.
fuente
Elegiría un nombre basado en la función principal del método. El hecho de que ese método devuelva un valor booleano no exige el prefijo 'Is'. Tengamos un código Java, que usa el prefijo 'Is' de forma bastante extensa. Echa un vistazo
java.io.File.delete()
. Regresaboolean
, pero no se llamaisFileDeleted()
. La razón es que la función principal del método es eliminar un archivo. Alguien llama a este método con la intención de eliminar un archivo.Lo booleano está ahí solo para comunicar el resultado del trabajo. Por otro lado, veamos
java.util.Map.isEmpty()
. Obviamente, llama a dicho método para averiguar si la colección está vacía. No quieres que se haga nada. Solo quiere saber cuál es el estado actual.Así que personalmente, definitivamente me quedaría con
DoStuff()
.Este es un tema muy importante para mí. Muchas veces, cuando mantengo el código heredado, me encuentro con algo que personalmente llamo "método de mentira". El nombre sugiere la acción A, pero el cuerpo realiza la acción B. El ejemplo más extraño es un método getter que cambia los datos en la base de datos.
fuente