Pregunta

Supongamos que tengo un método

public Patient(int id)
{
    ----
}

que devuelve un objeto Paciente dado un id. Yo podría definir el contrato de dos maneras

  1. El método devolverá el valor nulo si el paciente no existe
  2. El método lanzaría una excepción si el paciente no existe. En este caso, también definiría un método de consulta que devuelva verdadero si el Paciente existe en la base de datos o falso en otro caso ...

¿Qué contrato debo usar? ¿Alguna otra sugerencia?

Actualización: Por favor comente en este caso también ... Si no es un ID asignado a la base de datos y es algo que un usuario ingresa en la IU ... como SSN ... entonces cuál es mejor ...

Comente sobre el patrón nulo de Steve que creo que es válido: Probablemente no sea una buena idea aquí, ya que sería realmente útil saber de inmediato cuando no existía una identificación.

Y también creo que el patrón nulo aquí sería un poco pesado

Comentario de Rob Wells sobre el lanzamiento de una excepción porque es un Id. incorrecto: no creo que un error tipográfico en el nombre de un paciente sea una circunstancia excepcional " IMHO

¿Fue útil?

Solución

Ten en cuenta que pasar " por el cable " a otro nivel (ya sea una base de datos o un servidor de aplicaciones) es una de las actividades más caras que puede hacer; por lo general, una llamada de red tomará varios órdenes de magnitud más que las llamadas en memoria.

Por lo tanto, vale la pena estructurar tu API para evitar llamadas redundantes.

Considera, si tu API es así:

// Check to see if a given patient exists
public bool PatientExists(int id);

// Load the specified patient; throws exception if not found
public Patient GetPatient(int id);

Es probable que golpee la base de datos dos veces, o que confíe en un buen almacenamiento en caché para evitar esto.

Otra consideración es la siguiente: en algunos lugares, su código puede tener un " conocido-bueno " Identificación, en otros lugares no. Cada ubicación requiere una política diferente sobre si se debe lanzar una excepción.

Este es un patrón que he usado con buenos resultados en el pasado: tiene dos métodos:

// Load the specified patient; throws exception if not found
public Patient GetExistingPatient(int id);

// Search for the specified patient; returns null if not found
public Patient FindPatient(int id);

Claramente, GetExistingPatient () puede construirse llamando a FindPatient ().

Esto le permite a su código de llamada obtener el comportamiento adecuado, lanzar una excepción si algo salió mal y evitar el manejo de excepciones en los casos en que no sea necesario.

Otros consejos

Otra opción sería el Patrón de objeto nulo .

Probablemente deberías lanzar una excepción. Si tiene un id que no apunta a un paciente válido, ¿de dónde vino? Algo muy malo probablemente ha sucedido. Es una circunstancia excepcional.

EDITAR: Si está haciendo algo que no sea una recuperación basada en enteros, como una búsqueda basada en texto, entonces devolver null está bien. Especialmente porque en ese caso está devolviendo un conjunto de resultados, que podrían ser más de uno (más de un paciente con el mismo nombre, la misma fecha de nacimiento o cualquiera que sea su criterio).

Una función de búsqueda debe tener un contrato diferente de una función de recuperación.

Depende:

Si considera que la operación normal llevará a un número de pation que no coincide con un archivo en la base de datos, entonces se debe devolver un registro vacío (NULL).

Pero si espera que una ID determinada siempre llegue a un registro, cuando no se encuentre una (lo que debería ser raro) use una excepción.

Otras cosas, como un error de conexión a la base de datos, deberían generar una excepción.
Como se espera, en situaciones normales, la consulta al DB siempre funcionará (aunque puede devolver 0 registros o no).

P.S. No devolvería un puntero. (¿Quién posee el puntero?)
Devolvería un objeto que puede o no tener el registro. Pero que puede interogiarse por la existencia del registro interno. Potencialmente un puntero inteligente o algo un poco más inteligente que un puntero inteligente que entiende el cotext.

Para esta circunstancia, el método devuelve nulo para un paciente que no existe.

Tiendo a preferir el uso de excepciones para ayudar a la degradación grave cuando hay un problema con el sistema en sí.

En este caso, probablemente se deba:

  1. un error tipográfico en la identificación del paciente si se ingresó en un formulario de búsqueda,
  2. un error de entrada de datos, o
  3. un problema de flujo de trabajo en el que aún no se ha ingresado el registro del paciente.

Por lo tanto, devolver un valor nulo en lugar de una excepción.

Si hubiera un problema al contactar con la base de datos, entonces el método generaría una excepción.

Editar: Acabo de ver que la identificación del paciente en la firma era un número entero, gracias Steven Lowe, así que corregí mi lista de razones.

Mi punto básico acerca de delinear cuándo usar excepciones (para errores del sistema) versus otros métodos para devolver un error (para errores tipográficos de entrada de datos simples) sigue sin embargo. En mi humilde opinión.

HTH

saludos,

Rob

En una situación simple como esta 1. parece ser más que suficiente. Es posible que desee implementar algo así como un método de devolución de llamada que el cliente llame para saber por qué devolvió el valor nulo. Solo una sugerencia.

tomando su descriptiong a su valor nominal, es probable que necesite ambos:

  • las identificaciones incorrectas son errores / excepciones, como señaló Adam, pero
  • si le dan IDs en otros lugares que podrían haber desaparecido, necesitará el método de consulta para verificarlos

Suponiendo que lo haya leído correctamente ... Cuando llame al Paciente (100), devolverá una referencia de objeto para un Paciente con una identificación de 100. Si no existe ningún paciente con un ID de 100, creo que debería devolver un valor nulo. Las excepciones son sobreutilizadas IMO y este caso no lo requiere. La función simplemente devolvió un nulo. No creó ningún caso con error que pueda bloquear su aplicación (a menos que, por supuesto, usted no haya manejado ese nulo y se haya pasado a otra parte de su aplicación).

Definitivamente obtendría que la función devolviera 'nulo', especialmente si era parte de alguna búsqueda, donde un usuario buscaría un paciente con un ID particular y si la referencia del objeto terminaba siendo nula, simplemente afirmaría que no existe ningún paciente con esa identificación.

Lanzar una excepción.

Si devuelve un valor nulo, código como este:

Console.WriteLine(Patient(id).Name);

fallaría con una NullReferenceException si el ID no existe, lo que no es tan útil como, por ejemplo, una PatientNotFoundException (id). En este ejemplo, todavía es relativamente fácil de rastrear, pero considere:

somePatient = Patient(id)

// much later, in a different function:

Console.WriteLine(somePatient);

Acerca de agregar una función que verifique si existe un paciente: Tenga en cuenta que esto no impedirá que PatientNotFoundExceptions se realice por completo. Por ejemplo:

if (PatientExists(id))
    Console.WriteLine(Patient(id).Name);

: otro hilo u otro proceso podría eliminar al paciente entre las llamadas a PatientExists y Patient. Además, esto significaría dos consultas de base de datos en lugar de una. Por lo general, es mejor probar la llamada y controlar la excepción.

Tenga en cuenta que la situación es diferente para las consultas que devuelven varios valores, por ejemplo, como una lista; aquí, es apropiado devolver una lista vacía si no hay coincidencias.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top