Tengo un método que se supone que devuelve un objeto si se encuentra.
Si no se encuentra, debería:
- volver nulo
- lanzar una excepción
- otro
exception
error-handling
null
Robert
fuente
fuente
Respuestas:
Si siempre espera encontrar un valor, arroje la excepción si falta. La excepción significaría que hubo un problema.
Si el valor puede faltar o estar presente y ambos son válidos para la lógica de la aplicación, devuelva un valor nulo.
Más importante: ¿Qué haces en otros lugares del código? La consistencia es importante.
fuente
GetPersonById(25)
arrojaría si esa persona ha sido eliminada, peroGetPeopleByHairColor("red")
devolvería un resultado vacío. Entonces, creo que los parámetros dicen algo sobre las expectativas.Solo lanza una excepción si realmente es un error. Si se espera que el comportamiento del objeto no exista, devuelva el valor nulo.
De lo contrario, es una cuestión de preferencia.
fuente
Como regla general, si el método siempre debe devolver un objeto, entonces vaya con la excepción. Si anticipa un nulo ocasional y desea manejarlo de una manera determinada, vaya con el nulo.
Hagas lo que hagas, desaconsejo la tercera opción: devolver una cadena que dice "WTF".
fuente
Si nulo nunca indica un error, simplemente devuelva nulo.
Si nulo es siempre un error, arroje una excepción.
Si nulo es a veces una excepción, codifique dos rutinas. Una rutina arroja una excepción y la otra es una rutina de prueba booleana que devuelve el objeto en un parámetro de salida y la rutina devuelve un falso si no se encontró el objeto.
Es difícil hacer un mal uso de una rutina de prueba. Es muy fácil olvidarse de verificar nulo.
Entonces, cuando nulo es un error, simplemente escribes
Cuando el nulo no es un error, puede codificar algo como
fuente
find
yfindOrFail
de Laravel EloquentTryFindObject
método? Las tuplas parecen más un paradigma vago para los programadores que no quieren tomarse el tiempo para definir un objeto que encapsula múltiples valores. Eso es esencialmente todas las tuplas están en el núcleo de todos modos.Solo quería recapitular las opciones mencionadas anteriormente, agregando algunas nuevas en:
O puede combinar estas opciones:
Proporcione varias versiones sobrecargadas de su captador, para que la persona que llama pueda decidir qué camino tomar. En la mayoría de los casos, solo el primero tiene una implementación del algoritmo de búsqueda, y los otros simplemente envuelven el primero:
Incluso si elige proporcionar solo una implementación, es posible que desee utilizar una convención de nomenclatura como esa para aclarar su contrato, y le ayuda si alguna vez decide agregar otras implementaciones también.
No debe usarlo en exceso, pero puede ser útil, especialmente al escribir una clase auxiliar que usará en cientos de aplicaciones diferentes con muchas convenciones de manejo de errores diferentes.
fuente
Expected<T> findObject(String)
dondeExpected<T>
tiene las funcionesorNull()
,orThrow()
,orSupplied(Supplier<T> supplier)
,orDefault(T default)
. Esto abstrae la obtención de los datos del manejo de erroresUtilice el patrón de objeto nulo o arroje una excepción.
fuente
Person somePerson = personRepository.find("does-not-exist");
supongamos que este método devuelve un objeto nulo para IDdoes-not-exist
. ¿Cuál sería entonces el comportamiento correctosomePerson.getAge()
? En este momento, todavía no estoy convencido de que el patrón de objeto nulo sea la solución correcta para las búsquedas de entidades.Sea coherente con las API que está utilizando.
fuente
Ventajas de lanzar una excepción:
Para obtener más explicaciones con ejemplos, consulte: http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/
fuente
depende si tu idioma y código promueven: LBYL (mira antes de saltar) o EAFP (es más fácil pedir perdón que permiso)
LBYL dice que debe verificar los valores (así que devuelva un valor nulo)
EAFP dice que simplemente intente la operación y vea si falla (arroje una excepción)
aunque estoy de acuerdo con lo anterior ... las excepciones deben usarse para condiciones excepcionales / de error, y devolver un valor nulo es mejor cuando se usan cheques.
EAFP vs. LBYL en Python:
http://mail.python.org/pipermail/python-list/2003-May/205182.html ( Archivo Web )
fuente
Simplemente pregúntese: "¿es un caso excepcional que no se encuentre el objeto"? Si se espera que suceda en el curso normal de su programa, probablemente no debería generar una excepción (ya que no es un comportamiento excepcional).
Versión corta: use excepciones para manejar un comportamiento excepcional, no para manejar el flujo normal de control en su programa.
-Alan.
fuente
Las excepciones están relacionadas con el diseño por contrato.
La interfaz de un objeto es en realidad un contrato entre dos objetos, la persona que llama debe cumplir con el contrato o el receptor puede fallar con una excepción. Hay dos posibles contratos.
1) todas las entradas del método son válidas, en cuyo caso debe devolver nulo cuando no se encuentra el objeto.
2) solo alguna entrada es válida, es decir, la que da como resultado un objeto encontrado. En ese caso, DEBE ofrecer un segundo método que permita a la persona que llama determinar si su entrada será correcta. Por ejemplo
SI y SOLO SI proporciona ambos métodos del segundo contrato, puede lanzar una excepción, ¡no se encuentra nada!
fuente
Prefiero simplemente devolver un valor nulo y confiar en que la persona que llama lo maneje adecuadamente. La excepción (por falta de una palabra mejor) es si estoy absolutamente 'seguro' de que este método devolverá un objeto. En ese caso, una falla es un deber excepcional y debe arrojar.
fuente
Depende de lo que significa que el objeto no se encuentra.
Si se trata de una situación normal, devuelva nulo. Esto es algo que puede suceder de vez en cuando, y las personas que llaman deben verificarlo.
Si se trata de un error, arroje una excepción, las personas que llaman deben decidir qué hacer con la condición de error del objeto faltante.
En última instancia, cualquiera funcionaría, aunque la mayoría de las personas generalmente consideran una buena práctica usar Excepciones solo cuando algo, bueno, Excepcional ha sucedido.
fuente
Aquí hay un par de sugerencias más.
Si devuelve una colección, evite devolver nulo, devuelva una colección vacía, lo que hace que la enumeración sea más fácil de tratar sin una verificación nula primero.
Varias API de .NET usan el patrón de un parámetro thrownOnError que le da a la persona que llama la opción de si realmente es una situación excepcional o no si no se encuentra el objeto. Type.GetType es un ejemplo de esto. Otro patrón común con BCL es el patrón TryGet donde se devuelve un valor booleano y el valor se pasa a través de un parámetro de salida.
También puede considerar el patrón Objeto nulo en algunas circunstancias, que puede ser una versión predeterminada o una versión sin comportamiento. La clave es evitar verificaciones nulas en toda la base del código. Consulte aquí para obtener más información http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx
fuente
En algunas funciones agrego un parámetro:
Verdadero significa tirar, falso significa devolver algún valor de retorno de error. De esta manera, quien usa esta función tiene ambas opciones. El valor predeterminado debe ser verdadero, para beneficio de aquellos que se olvidan del manejo de errores.
fuente
Devuelva un valor nulo en lugar de lanzar una excepción y documente claramente la posibilidad de un valor de retorno nulo en la documentación de la API. Si el código de llamada no respeta la API y verifica el caso nulo, lo más probable es que resulte en algún tipo de "excepción de puntero nulo" de todos modos :)
En C ++, puedo pensar en 3 tipos diferentes de configurar un método que encuentre un objeto.
Opcion A
Devuelve nulo cuando no se puede encontrar un objeto. Agradable y simple Yo iría con este. Los enfoques alternativos a continuación son para personas que no odian a los paramáticos.
Opcion B
Pase una referencia a la variable que recibirá el objeto. El método arrojó una excepción cuando no se puede encontrar un objeto. Esta convención probablemente sea más adecuada si realmente no se espera que no se encuentre un objeto; por lo tanto, lanza una excepción para indicar que es un caso inesperado.
Opcion C
El método devuelve falso cuando no se puede encontrar un objeto. La ventaja de esto sobre la opción A es que puede verificar el caso de error en un paso claro:
fuente
refiriéndome solo al caso donde nulo no se considera un comportamiento excepcional, definitivamente estoy para el método de prueba, está claro, no es necesario "leer el libro" o "mirar antes de saltar" como se dijo aquí
así que básicamente:
y esto significa que el código del usuario también será claro
fuente
Si es importante que el código del cliente sepa la diferencia entre encontrado y no encontrado y se supone que este es un comportamiento de rutina, entonces es mejor devolver nulo. El código del cliente puede decidir qué hacer.
fuente
En general, debe devolver nulo. El código que llama al método debería decidir si lanzar una excepción o intentar otra cosa.
fuente
O devolver una opción
Una opción es básicamente una clase de contenedor que obliga al cliente a manejar casos de cabina. Scala tiene este concepto, busque su API.
Luego, tiene métodos como T getOrElse (T valueIfNull) en este objeto que devuelve el objeto encontrado o una alternativa que el cliente especifica.
fuente
Prefiero volver nulo -
Si la persona que llama lo usa sin verificar, la excepción ocurre allí de todos modos.
Si la persona que llama en realidad no lo uso, no lo gravar una
try
/catch
bloquefuente
Desafortunadamente, JDK es inconsistente, si intentas acceder a una clave no existente en el paquete de recursos, no obtienes una excepción y cuando solicitas valor del mapa, obtienes un valor nulo si no existe. Entonces, cambiaría la respuesta ganadora a lo siguiente, si el valor encontrado puede ser nulo, luego generaría una excepción cuando no se encuentre, de lo contrario, devolvería nulo. Así que siga la regla con una excepción, si necesita saber por qué no se encuentra el valor, siempre genere una excepción, o ...
fuente
Mientras se suponga que devuelve una referencia al objeto, devolver un NULL debería ser bueno.
Sin embargo, si devuelve todo lo sangriento (como en C ++ si lo hace: 'return blah;' en lugar de 'return & blah;' (o 'blah' es un puntero), entonces no puede devolver un NULL, porque es no del tipo 'objeto'. En ese caso, lanzar una excepción o devolver un objeto en blanco que no tenga un indicador de éxito establecido es cómo abordaría el problema.
fuente
No piense que nadie mencionó los gastos generales en el manejo de excepciones: se necesitan recursos adicionales para cargar y procesar la excepción, por lo que, a menos que sea un verdadero evento de cierre de la aplicación o de detención del proceso (en adelante, causaría más daño que bien) optaría por devolver un valorar el entorno de llamada podría interpretar como mejor le parezca.
fuente
Estoy de acuerdo con lo que parece ser el consenso aquí (devolver nulo si "no encontrado" es un resultado normal posible, o lanzar una excepción si la semántica de la situación requiere que siempre se encuentre el objeto).
Sin embargo, existe una tercera posibilidad que podría tener sentido dependiendo de su situación particular. Su método podría devolver un objeto predeterminado de algún tipo en la condición "no encontrado", lo que permite asegurar que el código de llamada siempre recibirá un objeto válido sin la necesidad de una comprobación nula o captura de excepciones.
fuente
Devuelva un valor nulo, las excepciones son exactamente eso: algo que hace su código que no se espera.
fuente
Las excepciones deben ser excepcionales . Devuelve nulo si es válido devolver un valor nulo .
fuente
Si el método devuelve una colección, devuelva una colección vacía (como se dijo anteriormente). ¡Pero por favor no Collections.EMPTY_LIST o tal! (en el caso de Java)
Si el método recupera un solo objeto, entonces tiene algunas opciones.
Tenga cuidado, si decide devolver un valor nulo. Si no es el único programador en el proyecto, obtendrá NullPointerExceptions (en Java o lo que sea en otros idiomas) en tiempo de ejecución. Por lo tanto, no devuelva valores nulos que no se verifican en tiempo de compilación.
fuente
null
. Vea la respuesta más votada para más.Si está utilizando una biblioteca u otra clase que arroja una excepción, debe volver a lanzar a . Aquí hay un ejemplo. Example2.java es como la biblioteca y Example.java usa su objeto. Main.java es un ejemplo para manejar esta excepción. Debe mostrar un mensaje significativo y (si es necesario) el seguimiento de la pila al usuario en el lado de la llamada.
Main.java
Example.java
Example2.java
fuente
Eso realmente depende de si espera encontrar el objeto, o no. Si sigue la escuela de pensamiento de que las excepciones deben usarse para indicar algo, bueno, err, excepcional ha ocurrido entonces:
De lo contrario, devuelva nulo.
fuente