2009-01-05 26 views
8

Supongamos que tengo un método¿Qué contrato (Diseño por contrato) es mejor?

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

que devuelve objeto paciente dado un id .. Me podría definir un contrato de 2 maneras

  1. método sería devuelto nulo si el paciente no existe
  2. método sería lanzar una excepción si el paciente no existe. En este caso, también definiría un método de consulta que devuelve verdadero si el paciente existe en la base de datos o es falso ...

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

Actualización: Por favor, comentar en este caso también ... Si no es una base de datos de identificación asignado y es algo que un usuario introduce en la interfaz de usuario .. como SSN .. entonces cuál es mejor ..

Comentario 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 existe una identificación.

Y También pienso patrón nulo en este caso sería peso algo pesado

comentario de Rob Wells en lanzar una excepción, ya que su mala identificación: que no creo que un error tipográfico en el nombre de un paciente es un excepcional en mi humilde opinión circunstancia"

Respuesta

15

Tenga en cuenta que ir "por cable" a otro nivel (ya sea una base de datos o un servidor de aplicaciones) es una de las actividades más costosas que puede hacer: generalmente una llamada de red tardará varios órdenes de magnitud más que en -memory llama.

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

tener en cuenta, si su API es la siguiente:

// 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); 

entonces es probable golpear la base de datos dos veces - o ser dependiente de la buena almacenamiento en caché para evitar esto.

Otra consideración es esta: en algunos lugares su código puede tener una identificación de "bien conocido", en otros lugares no. Cada ubicación requiere una política diferente sobre si se debe lanzar una excepción.

Aquí hay un patrón que he utilizado con buenos resultados en el pasado - tienen 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() se pueden construir llamando FindPatient().

Esto permite que su código de llamada obtenga el comportamiento apropiado, lanzando una excepción si algo salió mal y evitando el manejo de excepciones en los casos en que no es necesario.

+0

Bien por niveles alternativos. +1 –

+0

Impresionante ... Diseño por contrato – StackUnderflow

4

Otra opción sería la Null Object pattern.

+0

probablemente no sea una buena idea aquí, ya que sería realmente útil saber de inmediato cuando una identificación no existe. –

+0

Realmente no veo cómo sería un beneficio en este caso. –

+0

Sea o no un beneficio, pidió otras opciones; Es * IS * un beneficio para otros que más tarde leen esta pregunta para conocer esta opción. –

4

probablemente debería lanzar una excepción. Si usted tiene una id que no apunta a un paciente válida, ¿de dónde vienen? Algo muy malo es probable que haya sucedido. Es una circunstancia excepcional nce.

EDIT: Si estás haciendo algo que no sea una recuperación basada en el número entero, como una búsqueda basada en texto, a continuación, volver null está muy bien. Especialmente porque en ese caso está devolviendo un conjunto de resultados, que podría 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.

+0

+1 - ID incorrectos son errores/excepciones –

+0

no creo que un error tipográfico en el nombre de un paciente sea una circunstancia excepcional "IMHO –

+0

@ [Rob Wells]: la función en cuestión toma una ID entera como entrada, no la del paciente nombre –

1

En una situación tan 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 llama para saber por qué devolvió el valor nulo. Sólo una sugerencia.

2

Por esta circunstancia, tendría el método return null para un paciente inexistente.

Tiendo a preferir utilizar excepciones para ayudar a la degradación grave cuando hay un problema con el sistema.

En este caso, es mosdt probablemente:

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

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

Si hubo un problema al contactar la base de datos, entonces me gustaría hacer que el método genere 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 he corregido mi lista de razones.

Mi punto básico sobre delinear cuándo usar las excepciones (para los errores del sistema) frente a otros métodos de devolver un error (para los errores de ingreso de datos simples) sigue en pie. EN MI HUMILDE OPINIÓN.

HTH

aplausos,

Rob

1

tomar su descriptiong a su valor nominal, es probable que necesitan tanto:

  • identificadores malos son errores/excepciones, como Adán señaló, pero
  • si le dan identificadores en otro lugar que podrían haber desaparecido, necesitará el método de consulta para verificar el m
0

Suponiendo que leí correctamente ... Cuando se llama a paciente (100) devolverá una referencia de objeto para un paciente con un id de 100. Si no existe ningún paciente con un diámetro interior de 100, lo Creo que debería regresar nulo. Las excepciones son OMI sobreutilizadas y este caso no lo requiere. La función simplemente devolvió un nulo. No creó ningún caso de error que pueda bloquear su aplicación (a menos que, por supuesto, termine no manejando ese nulo y lo pase a alguna otra parte de su aplicación).

Definitivamente tendré esa función como 'nula', especialmente si era parte de alguna búsqueda, donde un usuario buscaría a un paciente con una ID particular y si la referencia del objeto terminara siendo nula, simplemente indicaría que no existe ningún paciente con ese id.

2

Depende:

Si se tiene en cuenta el funcionamiento normal dará lugar a un número pación que no coincida con un archivo en la base de datos a continuación, un (NULL) registro vacío debe ser devuelto.

Pero si espera que una identificación dada siempre golpee un registro y luego cuando no se encuentra uno (lo que debería ser raro), utilice una excepción.

Otras cosas como un error de conexión de base de datos deben generar una excepción.
Como espera en situaciones normales, la consulta al DB siempre funciona (aunque puede devolver 0 registros o no).

P.S. No devolvería un puntero. (¿A quién pertenece el puntero?)
Devolvería un objeto que puede o no tener el registro. Pero que puede interponerse para la existencia del registro dentro. Potencialmente un puntero inteligente o algo un poco más inteligente que un puntero inteligente que entiende el cotexto.

0

Lance la excepción.

Si devuelve nulo, código como este:

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

podría fallar con un NullReferenceException si el ID no existe, que no es tan útil como dicen que un PatientNotFoundException (id). En este ejemplo, sigue siendo relativamente fácil de localizar, pero tenga en cuenta:

somePatient = Patient(id) 

// much later, in a different function: 

Console.WriteLine(somePatient); 

Acerca de la adición de una función que comprueba si existe un paciente: Nota esto no impedirá PatientNotFoundExceptions por completo. Por ejemplo:

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

- otro hilo u otro proceso podría eliminar el paciente entre las llamadas a PatientExists y paciente. Además, esto significaría dos consultas a la base de datos en lugar de una. Por lo general, es mejor simplemente intentar la llamada y manejar la excepción.

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

Cuestiones relacionadas