Question

Supposons que j'ai une méthode

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

qui retourne un objet Patient avec un identifiant. Je pourrais définir un contrat de 2 façons

  1. La méthode renverrait la valeur null si le patient n'existe pas
  2. La méthode lève une exception si le patient n'existe pas. Dans ce cas, je définirais également une méthode de requête qui renvoie true si le patient existe dans la base de données ou false sinon ...

Quel contrat dois-je utiliser? D'autres suggestions?

Mise à jour: veuillez également commenter ce cas ... S'il ne s'agit pas d'un identifiant de base de données attribué à un utilisateur et que c'est quelque chose qu'un utilisateur entre dans l'interface utilisateur .. comme SSN .. alors lequel est le meilleur ..

Commentaire sur le motif Null de Steve que je pense être valide: Ce n’est probablement pas une bonne idée ici, car il serait vraiment utile de savoir immédiatement quand un identifiant n’existait pas.

Et je pense aussi que le motif Null serait un peu lourd

Commentaire de Rob Wells sur l’exception de projection car son mauvais identifiant: Je ne pense pas qu'une faute de frappe au nom d'un patient soit une circonstance exceptionnelle " IMHO

Était-ce utile?

La solution

N'oubliez pas que vous devez passer par le fil " Le passage à une autre couche (base de données ou serveur d’application) est l’une des activités les plus coûteuses. En général, un appel réseau prend plusieurs ordres de grandeur plus longtemps que les appels en mémoire.

Il est donc utile de structurer votre API pour éviter les appels redondants.

Considérez si votre API est comme ceci:

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

Vous risquez alors de frapper deux fois sur la base de données ou de vous fier à une bonne mise en cache pour éviter cela.

Une autre considération est la suivante: à certains endroits, votre code peut avoir la mention "bien connu". id, dans d'autres endroits pas. Chaque emplacement nécessite une stratégie différente selon le choix d'une exception.

Voici un modèle que j'ai utilisé à bon escient dans le passé - utilisez deux méthodes:

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

Clairement, GetExistingPatient () peut être créé en appelant FindPatient ().

Cela permet à votre code d'appel d'obtenir le comportement approprié, en lançant une exception si quelque chose ne va pas et en évitant la gestion des exceptions dans les cas où cela n'est pas nécessaire.

Autres conseils

Une autre option serait le Modèle d'objet nul .

Vous devriez probablement lever une exception. Si vous avez un id qui ne pointe pas vers un patient valide, d'où vient-il? Quelque chose de très grave est probablement arrivé. C'est une circonstance exceptionnelle.

MODIFIER: si vous effectuez autre chose qu'une récupération basée sur un entier, comme une recherche basée sur du texte, le renvoi de null est acceptable. Surtout que dans ce cas, vous renvoyez un ensemble de résultats, qui peuvent être plusieurs (plusieurs patients portant le même nom, la même date de naissance ou vos critères).

Une fonction de recherche doit avoir un contrat différent d’une fonction de récupération.

Cela dépend:

Si vous considérez que l'opération normale entraînera un numéro de pation ne correspondant pas à un fichier de la base de données, un enregistrement vide (NULL) doit être renvoyé.

Mais si vous vous attendez à ce qu'un identifiant donné frappe toujours un enregistrement, vous devrez utiliser une exception si vous ne le trouvez pas (ce qui devrait être rare).

Une erreur de connexion à la base de données doit également générer une exception, par exemple.
Comme vous vous y attendez dans des situations normales, la requête à la base de données fonctionne toujours (même si elle peut renvoyer 0 enregistrement ou non).

P.S. Je ne renverrais pas de pointeur. (À qui appartient le pointeur ??)
Je voudrais retourner un objet qui peut ou peut ne pas avoir le dossier. Mais que vous pouvez interoger pour l'existence du disque à l'intérieur. Peut-être un pointeur intelligent ou quelque chose de légèrement plus intelligent qu'un pointeur intelligent qui comprend le cotext.

Dans ce cas, la méthode renvoie null pour un patient inexistant.

J'ai tendance à préférer utiliser des exceptions pour aider à la dégradation grave lorsque le système lui-même pose problème.

Dans ce cas, il est probablement plus probable:

  1. une faute de frappe dans l'ID du patient si elle a été entrée dans un formulaire de recherche,
  2. une erreur de saisie de données ou
  3. un problème de flux de travail dans le sens où le dossier du patient n'a pas encore été saisi.

Par conséquent, renvoyer un null plutôt qu'une exception.

Si un problème survient lors du contact avec la base de données, la méthode devrait générer une exception.

Modifier: Nous venons de voir que l'identifiant du patient dans la signature était un entier, merci Steven Lowe. J'ai donc corrigé ma liste de raisons.

Mon point de base sur la définition du moment où utiliser des exceptions (pour les erreurs système) par rapport à d'autres méthodes permettant de renvoyer une erreur (pour les fautes de frappe simples) reste cependant. IMHO.

HTH

acclamations,

Rob

Dans une situation simple comme celle-ci 1. semble être plus que suffisant. Vous souhaiterez peut-être implémenter quelque chose comme une méthode de rappel que le client appelle pour savoir pourquoi elle a renvoyé la valeur null. Juste une suggestion.

Si vous prenez votre description comme telle, vous aurez probablement besoin des deux:

  • les mauvais identifiants sont des erreurs / exceptions, comme l'a souligné Adam, mais
  • si des identifiants ont disparu ailleurs, vous aurez besoin de la méthode de requête pour les rechercher

En supposant que j'ai lu cela correctement ... Lorsque vous appelez Patient (100), une référence d'objet est renvoyée pour un patient dont l'identifiant est 100. Si aucun patient avec un identifiant de 100 n'existe, je pense qu'il devrait renvoyer null. Les exceptions sont une utilisation excessive de l’OMI et cette affaire ne le demande pas. La fonction a simplement retourné un null. Cela n'a pas créé de casse erronée susceptible de provoquer le blocage de votre application (à moins bien sûr que vous n'ayez pas géré cette valeur et que vous l'avez transmis à une autre partie de votre application).

Je voudrais certainement que cette fonction renvoie la valeur "null", en particulier si elle faisait partie d'une recherche, où un utilisateur rechercherait un patient avec un ID particulier et si la référence de l'objet finissait par être null, elle indiquerait simplement que aucun patient avec cet identifiant n'existe.

Lance une exception.

Si vous renvoyez une valeur nulle, utilisez le code suivant:

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

échouerait avec une exception NullReferenceException si l'id n'existe pas, ce qui n'est pas aussi utile que de dire une exception PatientNotFoundException (id). Dans cet exemple, il est encore relativement facile à localiser, mais considérons:

somePatient = Patient(id)

// much later, in a different function:

Console.WriteLine(somePatient);

À propos de l'ajout d'une fonction qui vérifie l'existence d'un patient: Notez que cela n'empêchera pas complètement PatientNotFoundExceptions. Par exemple:

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

- un autre thread ou un autre processus peut supprimer le patient entre les appels à PatientExists et à Patient. En outre, cela signifierait deux requêtes de base de données au lieu d'une. Habituellement, il est préférable d’essayer simplement l’appel et de gérer l’exception.

Notez que la situation est différente pour les requêtes qui renvoient plusieurs valeurs, par exemple. sous forme de liste; Dans ce cas, il convient de renvoyer une liste vide s'il n'y a pas de correspondance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top