53 votes

À qui revient la responsabilité de vérifier la validité des données?

Je suis confus quant à savoir si c'est l'appelant ou la responsabilité de vérifier l'appelé de la légalité des données.

L' appelé doit-il vérifier si les arguments transmis ne doivent pas être null et répondre à certaines autres exigences afin que la méthode appelée puisse s'exécuter normalement et avec succès, et pour détecter d'éventuelles exceptions? Ou est-ce que l' appelant a la responsabilité de le faire?

74voto

duffymo Points 188155

Les deux secondaires du consommateur(client) et fournisseur de côté(API) de validation.

Les Clients doivent le faire parce que cela signifie une meilleure expérience. Par exemple, pourquoi un réseau autour le voyage vient d'être dit que vous avez un mauvais champ de texte?

Les fournisseurs doivent le faire parce qu'ils devraient jamais la confiance des clients (p. ex. XSS et de l'homme dans le milieu des attaques). Comment savez-vous la demande n'a pas intercepté? Valider le tout.

Il existe plusieurs niveaux de valide:

  1. Tous les champs présents, corriger les formats. C'est ce que le client valide.
  2. # 1 plus valide les relations entre les champs (par exemple, si X est présent, alors Y est obligatoire).
  3. # 1 et # 2 en plus d'entreprise valide: conforme à toutes les règles métier pour le traitement approprié.

Seul le fournisseur côté peut faire #2 et #3.

19voto

Thihara Points 3969

Pour une API, l'appelé doit toujours effectuer la validation appropriée et émettre une exception descriptive pour les données non valides.

Pour tout client avec surcharge IO, le client doit également effectuer une validation de base ...

11voto

JustinC Points 356

Validation: identification de l'Appelé vs

Le TLDR version est à la fois.

La version longue, consiste à qui, pourquoi, quand, comment, et avec quoi.

Les deux

Les deux devraient être prêts à répondre à la question "ces données peuvent être opérés de manière fiable?" Ne nous en savons assez sur ces données pour faire quelque chose de significatif? Beaucoup suggèrent que la fiabilité des données ne doit jamais être digne de confiance, mais qui ne conduit qu'à la poule et de l'œuf problème. Chasser à l'infini dans les deux bouts de ne pas prévoir d'ajouter de la valeur, mais à un certain degré, il est essentiel.

Les deux doivent valider la forme de données afin de s'assurer de la base de la convivialité. Si l'on ne reconnaît pas ou ne comprennent pas la forme des données, il n'y a aucun moyen de savoir comment le manipuler avec toute la fiabilité. Selon l'environnement, les données peuvent avoir besoin d'être un "type", qui est souvent un moyen facile de valider la forme. Nous considérons souvent que les types de présenter des éléments de preuve de la commune de linage de retour d'un ancêtre particulier et de conserver l'essentiel des traits de posséder la bonne forme. D'autres caractéristiques peut être important si les données n'est rien d'autre qu'une structure de mémoire, par exemple si c'est un cours d'eau ou toute autre ressource externe de l'exécution de contexte.

De nombreuses langues inclure des données de la forme de la vérification comme un langage intégré une fonctionnalité via le type d'interface ou de la vérification. Toutefois, lorsque favorisant la composition au cours de l'héritage, en fournissant un bon moyen de vérifier trait existence incombe au maître d'œuvre. Une stratégie pour y parvenir est par le biais de la programmation dynamique, ou en particulier par le type d'introspection, de l'inférence, ou de réflexion.

Appelé

L'appelé doit valider le domaine (l'ensemble des intrants) le contexte dans lequel il va opérer. La conception de l'appelle toujours l'indique, il ne peut traiter que les cas d'entrée. Habituellement, ces valeurs sont séparés dans certaines sous-classes ou des catégories de l'entrée. Nous vérifions le domaine de l'appelé parce que l'appelé est intime avec la version localisée de contraintes. Il sait mieux que quiconque ce qui est bon d'entrée, et ce qui ne l'est pas.

  • Valeurs normales: Ces valeurs du domaine de la carte à une plage. Pour chaque foo il y a un et un seul bar.

  • En dehors de la plage/hors de la portée des valeurs: Ces valeurs font partie du domaine général, mais pas de carte pour une plage dans le contexte de l'appelé. Aucun comportement défini existe pour ces valeurs, et donc pas de sortie est possible. Souvent hors de portée de la vérification implique de gamme, de limiter ou de caractères autorisés (ou de chiffres, ou composite des valeurs). Une cardinalité vérifier (multiplicité) et par la suite, un contrôle de présence (null ou vide), des formes particulières de contrôle de la portée.

  • Valeurs qui conduisent à la Illogique ou un comportement indéfini: Ces valeurs sont des valeurs spéciales, ou des cas limites, qui sont normaux, mais en raison de la conception d'un algorithme connu et contraintes d'environnement, serait de produire des résultats inattendus. Par exemple, une fonction qui opère sur des nombres en garde contre la division par zéro ou des accumulateurs qui serait un dépassement de capacité ou involontaire de la perte de précision. Parfois, l'environnement d'exploitation ou le compilateur peut avertir que ces situations peuvent se produire, mais en s'appuyant sur le moteur d'exécution ou le compilateur n'est pas une bonne pratique car il ne peut pas toujours être capables de déduire ce qui est possible et ce qui ne l'est pas. Cette étape devrait être en grande partie à la vérification, par l'intermédiaire de la validation, que l'appelant a fourni bon, utilisable, des commentaires pertinents.

L'appelant

L'appelant est spécial. L'appelant a deux situations dans lesquelles il doit valider les données.

La première situation est sur la cession ou explicite les modifications de l'état, lorsqu'un changement se produit à au moins un élément de données par quelque mécanisme explicite, à l'interne ou à l'externe par quelque chose dans son conteneur. C'est un peu hors de portée de la question, mais quelque chose à garder à l'esprit. L'important est de tenir compte du contexte lorsqu'un changement d'état se produit, et un ou plusieurs éléments qui décrivent l'état sont affectés.

  • Auto/Intégrité Référentielle: Envisager l'utilisation d'un mécanisme interne pour valider l'état si d'autres acteurs peuvent faire référence aux données. Lorsque les données n'a pas de contrôles de cohérence, il n'est sûr de supposer qu'il est dans un état indéterminé. Ce n'est pas intermédiaire, mais de durée indéterminée. Connais-toi toi-même. Lorsque vous n'utilisez pas un mécanisme permettant de valider la cohérence interne de changement d'état, les données ne sont pas fiables et qui entraîne des problèmes dans la seconde situation. Assurez-vous que les données de l'appelant est dans un état de bonne santé; sinon, dans une connue de transition/état de récupération. Ne pas faire l'appel jusqu'à ce que vous êtes prêt.

La deuxième situation est lorsque les données des appels d'une fonction. Un appelant peut s'attendre qu'à tellement de l'appelé. L'appelant doit connaître et respecter que l'appelé ne reconnaît qu'un certain domaine. L'appelant doit également être intéressées, comme il peut continuer et persister longtemps après l'appelé se termine. Cela signifie que l'appelant doit aider à la appelé à être non seulement un succès, mais également appropriée pour la tâche: les données erronées dans le produit de mauvaises données. Sur la même, de même de bonnes données et dans le respect de l'appelé peut ne pas être approprié pour la prochaine chose en termes de l'appelant. Les bonnes données peuvent effectivement être mauvais de données pour l'appelant. La sortie de l'appelé peut invalider l'appelant de l'appelant dans son état actuel.

Ok, assez de commentaire, ce qui devrait l'appelant valider en particulier?

  • Normal et logique: les données, est appelé une bonne stratégie que s'inscrit le but et l'intention? Si nous savons que ce sera un échec avec certaines valeurs, il n'y a pas de point dans l'exécution de l'appel sans gardes, la plupart du temps. Si nous savons que l'appelé ne peut pas gérer de zéro, ne le demande pas à ce qu'il ne réussira jamais. Ce qui est plus cher et plus difficile à gérer: un [redondant (en savons-nous?)] la garde de la clause, ou une exception [qui survient à la fin d'une longue course, à l'extérieur de ressources disponibles dépendant de processus]? Les implémentations peuvent changer, et changer tout d'un coup. En fournissant la protection de l'appelant réduit l'impact et les risques dans l'évolution de la mise en œuvre.

  • Les valeurs de retour: vérifiez l'inaboutissement. C'est quelque chose que l'appelant peut ou peut ne pas avoir besoin de le faire. Avant d'utiliser ou en s'appuyant sur les données renvoyées, vérifier alternative résultats, si la conception du système intègre le succès et l'échec des valeurs qui peuvent accompagner la valeur de retour.

Note de bas de page: Dans le cas où c'était pas clair. La valeur Null est un problème de domaine. Il peut ou peut ne pas être logique et normal, donc ça dépend. Si la valeur null est naturel d'entrée à une fonction, et la fonction peut être raisonnable de s'attendre à produire des sortie, puis le laisser à l'appelant pour l'utiliser. Si le domaine de l'appelant est telle que null n'est pas logique, alors garde contre elle dans les deux endroits.

Une question importante: si vous êtes de passage à null pour les appelés, et les appelés, est la production de quelque chose, n'est-ce pas caché creational modèle, de créer quelque chose à partir de rien?

9voto

Piotr Gwiazda Points 5208

Il est tout au sujet de "contrat". C'est un appel qui décide quels sont les paramètres qui sont bien ou non. Vous pouvez la mettre dans la documentation qu'un "null" paramètre invalide, puis de le jeter NullPointerException ou InvalidArgumentException est fine.

Si retournant un résultat pour le paramètre null sens - de l'état dans la documentation. Habituellement une telle situation est une mauvaise conception - créer une méthode surchargée avec moins de paramètres au lieu d'accepter la valeur null.

Seulement rappelez-vous de jeter descriptif des exceptions. Par une règle de base:

  1. Si l'appelant passé de mauvais arguments, différent de celui décrit dans la documentation (c'est à dire nulle, id < 0, etc) - jeter un décoché exception (NullPointerException ou InvalidArgumentException)
  2. Si l'appelant transmis arguments corrects mais il y a peut être attendue d'un cas d'entreprise qui fait qu'il est impossible de traiter l'appel - vous pouvez jeter un activée descriptif exception. Par exemple - pour getPermissionsForUser(Integer userId) l'appelant passe userId ne sachant pas si l'utilisateur existe, mais c'est un non-null Entier. Votre méthode peut retourner une liste d'autorisations ou thorw un UserNotFoundException. Il peut être vérifié exception.
  3. Si les paramètres sont corrects en fonction de la documentation, mais elles entraîne le traitement de l'erreur interne - vous pouvez jeter un décoché exception. Cela signifie généralement que votre méthode n'est pas bien testé ;-)

4voto

Marco Forberg Points 2163

Eh bien... ça dépend.

Si vous pouvez être sûr de savoir comment gérer les données non valides à l'intérieur de votre correspondant puis le faire.

Si vous n'êtes pas sûr (par exemple, parce que votre méthode est très générale et utilisé dans différents lieux et des moyens), puis laissez-le décider de l'appelant.

Par exemple, imaginez un DAO Méthode pour récupérer une certaine entité et vous ne le trouvez pas. Pouvez-vous décider de lancer une exception, peut-être annuler une transaction ou à la juste considèrent qu'il est d'accord? Dans un tel cas, il est certainement à l'appelant de décider de la façon de le gérer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X