J'ai écrit une structure qui représente les coordonnées de latitude / longitude. Leurs valeurs vont de -180 à 180 pour les longtitudes et de 90 à -90 pour les latitudes.
Si un utilisateur de cette structure me donne une valeur en dehors de cette plage, j'ai 2 options:
- Lancer une exception (argument hors limites)
- Convertir la valeur en contrainte
Parce qu'une coordonnée de -185 a une signification (elle peut très facilement être convertie en +175 car ce sont des coordonnées polaires), je pourrais l'accepter et la convertir.
Est-il préférable de lancer une exception pour dire à l'utilisateur que son code m'a donné une valeur qu'il ne devrait pas avoir?
Edit: De plus, je connais la différence entre lat / lng et les coordonnées, mais je voulais simplifier cela pour faciliter la discussion - ce n’était pas la plus brillante des idées
la source
Réponses:
Si le cœur de votre question est la suivante ...
... alors ma réponse générale serait "rejeter", car cela aidera à attirer l’attention sur les bogues potentiels du code client qui font en sorte que la valeur non valide apparaisse dans le programme et atteigne votre constructeur. Attirer l'attention sur les bogues est généralement une propriété souhaitée dans la plupart des systèmes, du moins pendant le développement (à moins que ce ne soit une propriété souhaitée de votre système que de se débrouiller en cas d'erreur).
La question est de savoir si vous êtes réellement confronté à ce cas .
Si votre structure de données est conçue pour modéliser les coordonnées polaires en général, acceptez la valeur, car les angles hors de la plage -180 et +180 ne sont pas vraiment invalides. Elles sont parfaitement valables et ont toujours un équivalent compris entre -180 et +180 (et si vous souhaitez les convertir pour cibler cette plage, n'hésitez pas, le code du client n’a généralement pas besoin de soins). .
Si votre structure de données modélise explicitement les coordonnées Web Mercator (en fonction de la question dans sa forme initiale), il est préférable de suivre les dispositions mentionnées dans le cahier des charges (ce que je ne connais pas, je ne le dirai donc pas). . Si la spécification de la chose que vous modélisez indique que certaines valeurs ne sont pas valides, rejetez-les. S'il est dit qu'ils peuvent être interprétés comme quelque chose de sensé (et qu'ils sont donc valables), acceptez-les.
Le mécanisme que vous utilisez pour indiquer si les valeurs ont été acceptées ou non dépend des caractéristiques de votre langue, de sa philosophie générale et de vos exigences de performance. Donc, vous pouvez lancer une exception (dans le constructeur) ou renvoyer une version nullable de votre structure (via une méthode statique qui appelle un constructeur privé) ou renvoyer un booléen et transmettre votre structure à l'appelant en tant que
out
paramètre méthode statique qui appelle un constructeur privé), etc.la source
Ça dépend beaucoup. Mais vous devriez décider de faire quelque chose et le documenter .
La seule mauvaise chose à faire pour votre code est d'oublier de considérer que la saisie de l'utilisateur peut être en dehors de la plage attendue et d'écrire du code qui a un comportement accidentel. Parce qu'alors, certaines personnes émettront une hypothèse erronée sur le comportement de votre code, ce qui causera des bogues, alors que d'autres finiront par dépendre du comportement que votre code aura accidentellement (même si ce comportement est totalement dingue) et vous causerez donc plus de bugs. quand vous résolvez le problème plus tard.
Dans ce cas, je peux voir les arguments de toute façon. Si quelqu'un se déplace de +10 degrés à partir de 175 degrés, il devrait se retrouver à -175. Si vous normalisez toujours les entrées utilisateur et que vous considérez ainsi 185 comme équivalent à -175, le code client ne peut pas agir de manière erronée lorsqu'il ajoute 10 degrés; ça a toujours le bon effet. Si vous traitez 185 comme une erreur , vous obligez tous les cas où le code client ajoute degrés par rapport à mettre dans la logique de normalisation (ou au moins ne pas oublier d'appeler votre procédure de normalisation), vous aurez réellement la causebugs (même si espérons facile à attraper ceux qui seront rapidement écrasés). Mais si un numéro de longitude est saisi par l'utilisateur, écrit littéralement dans le programme ou calculé selon une procédure destinée à toujours figurer en [-180, 180), une valeur située en dehors de cet intervalle risque très probablement d'indiquer une erreur. "le convertir pourrait cacher des problèmes.
Mon idéal dans ce cas serait probablement de définir un type qui représente le bon domaine. Utilisez un type abstrait (ne laissez pas le code client simplement accéder aux nombres bruts qu'il contient) et fournissez à la fois une fabrique de normalisation et une fabrique de validation (afin que le client puisse faire le compromis). Mais quelle que soit la valeur de ce type, 185 doit être identique à -175 vu par votre API publique (qu’ils soient convertis à la construction ou que vous fournissiez une égalité, des accesseurs et d’autres opérations qui ignorent la différence d’une manière ou d’une autre). .
la source
Si le choix d'une solution ne vous intéresse pas vraiment, vous pouvez laisser l'utilisateur décider.
Étant donné que votre structure est un objet de valeur en lecture seule et créée par une méthode / un constructeur, vous pouvez fournir deux surcharges basées sur les options dont dispose l'utilisateur:
De même, ne laissez jamais l'utilisateur avoir une structure non valide à transmettre à vos autres méthodes, réglez-le correctement lors de la création.
Edit: basé sur les commentaires, je suppose que vous utilisez c #.
la source
catch
vos exceptions. Comme d’autres l’ont dit, c’est pour permettre au client de se limiter s’il le souhaite. Vous ne contournez vraiment rien.Cela dépend si l'entrée provient directement d'un utilisateur via une interface utilisateur ou du système.
Entrée via une interface utilisateur
Il s’agit d’une question d’expérience utilisateur sur la gestion des entrées non valides. Je ne connais pas votre cas particulier, mais en général, il y a quelques options:
Le choix dépend des attentes de vos utilisateurs et de l’importance des données. Par exemple, Google corrige automatiquement l'orthographe dans les requêtes, mais le risque est faible, car une modification peu utile ne pose pas de problème et est facile à corriger (et même dans ce cas, il est clairement indiqué sur la page de résultat que la requête a été modifiée). D'autre part, si vous entrez les coordonnées d'un missile nucléaire, vous souhaiterez peut-être une validation d'entrée plus rigide et aucune solution silencieuse des données non valides. Donc, il n'y a pas de réponse universelle.
Plus important encore, vous devez vous demander si la correction d'une saisie présente un avantage pour l'utilisateur. Pourquoi un utilisateur entrerait-il des données invalides? Il est facile de voir comment quelqu'un pourrait faire une faute d'orthographe, mais pourquoi quelqu'un entrerait-il une longitude de -185? Si l'utilisateur voulait vraiment dire +175, il aurait probablement tapé +175. Je pense qu'il est fort probable qu'une longitude non valide soit simplement une erreur de frappe, et l'utilisateur voulait dire -85 ou quelque chose d'autre. Dans ce cas, la conversion en silence est mauvaise et inutile . L’approche la plus conviviale pour votre application consisterait probablement à alerter l’utilisateur de la valeur non valide et à lui demander de la corriger elle-même.
Entrée via une API
Si l'entrée provient d'un autre système ou sous-système, il n'y a pas de doute. Vous devriez lancer une exception. Vous ne devriez jamais rendre silencieuse la conversion d'une entrée non valide d'un autre système, car cela pourrait masquer des erreurs ailleurs dans le système. Si l'entrée est "corrigée", cela devrait se produire dans la couche d'interface utilisateur et non plus profondément dans le système.
la source
Vous devriez lancer une exception.
Dans l'exemple que vous avez donné, en envoyant 185 et en convertissant cela en -175, il peut être utile dans certains cas de fournir cette fonctionnalité. Mais que faire si l'appelant envoie 1 million? Veulent-ils vraiment convertir cela? Il semble plus probable que ce soit une erreur. Donc, si vous devez lever une exception pour 1 000 000 mais pas pour 185, vous devez alors prendre une décision concernant un seuil arbitraire pour le lancement d'une exception. Ce seuil va vous faire trébucher un jour, car une application appelante envoie des valeurs autour du seuil.
Mieux vaut jeter l'exception pour les valeurs hors de la plage.
la source
L'option la plus pratique pour un développeur serait un support d'erreur de compilation lors de la plate-forme, pour les valeurs hors limites. Dans ce cas, la plage doit également faire partie de la signature de la méthode, tout comme le type des paramètres. De la même manière que votre utilisateur d'API ne peut pas transmettre une chaîne si la signature de votre méthode est définie pour accepter un entier , l'utilisateur ne devrait pas pouvoir transmettre une valeur sans vérifier si la valeur se situe dans la plage indiquée dans la signature de la méthode. S'il n'est pas coché, il devrait obtenir une erreur de compilation et ainsi, une erreur d'exécution pourrait être évitée.
Mais actuellement, très peu de compilateurs / plates-formes supportent ce type de vérification du temps de compilation. C'est donc un casse-tête pour les développeurs. Mais idéalement, votre méthode devrait simplement générer une exception significative pour les valeurs non prises en charge et la documenter clairement.
BTW, j'aime vraiment le modèle d'erreur proposé par Joe Duffy ici .
la source
La valeur par défaut devrait être de lancer une exception. Vous pouvez également autoriser une option telle que
strict=false
et exercer la contrainte en fonction du drapeau, oùstrict=true
est bien sûr la valeur par défaut. Ceci est assez commun:DateFormat
supporte clément .la source
strict=false
?Pour moi, la meilleure pratique consiste à ne jamais modifier les entrées de l'utilisateur. L'approche que je prends habituellement consiste à séparer la validation de l'exécution.
la source