J'avais l'impression que maintenant tout le monde était d'accord que cette maxime était une erreur. Mais j'ai récemment vu cette réponse qui a un commentaire "soyez indulgents" voté 137 fois (à ce jour).
À mon avis, la clémence dans ce que les navigateurs acceptent était la cause directe du désordre absolu que HTML et certaines autres normes Web étaient il y a quelques années, et n'ont commencé à se cristalliser correctement que récemment. La façon dont je le vois, être clément dans ce que vous acceptez va conduire à cela.
La deuxième partie de la maxime est «éliminer silencieusement les entrées défectueuses, sans renvoyer un message d'erreur à moins que cela ne soit requis par la spécification» , et cela semble offensant à la limite. Tout programmeur qui s'est cogné la tête contre le mur quand quelque chose échoue silencieusement saura ce que je veux dire.
Alors, je me trompe complètement à ce sujet? Mon programme doit-il être indulgent dans ce qu'il accepte et avaler les erreurs en silence? Ou suis-je mal interprété ce que cela est censé signifier?
La question initiale disait «programme», et je comprends tout le monde à ce sujet. Il peut être logique que les programmes soient indulgents. Ce que je voulais vraiment dire, cependant, ce sont les API: des interfaces exposées à d' autres programmes , plutôt qu'à des personnes. HTTP est un exemple. Le protocole est une interface que seuls les autres programmes utilisent. Les gens ne fournissent jamais directement les dates qui entrent dans des en-têtes comme "If-Modified-Since".
Donc, la question est: le serveur implémentant une norme doit-il être indulgent et autoriser les dates dans plusieurs autres formats, en plus de celui qui est réellement requis par la norme? Je crois que "être indulgent" est censé s'appliquer à cette situation, plutôt qu'aux interfaces humaines.
Si le serveur est indulgent, cela peut sembler une amélioration globale, mais je pense qu'en pratique, cela ne mène qu'à des implémentations client qui finissent par s'appuyer sur la clémence et donc à ne pas travailler avec un autre serveur qui est indulgent de manière légèrement différente.
Donc, un serveur exposant une API devrait-il être indulgent ou est-ce une très mauvaise idée?
Passons maintenant à la gestion clémente des entrées utilisateur. Considérez YouTrack (un logiciel de suivi des bogues). Il utilise une langue pour la saisie de texte qui rappelle Markdown. Sauf que c'est "indulgent". Par exemple, écrire
- foo
- bar
- baz
n'est pas un moyen documenté de créer une liste à puces, et pourtant cela a fonctionné. Par conséquent, il a fini par être beaucoup utilisé dans notre bugtracker interne. La version suivante sort, et cette fonctionnalité indulgente commence à fonctionner légèrement différemment, cassant un tas de listes qui ont (mal) utilisé cette (non) fonctionnalité. La manière documentée de créer des listes à puces fonctionne toujours, bien sûr.
Alors, mon logiciel doit-il être indulgent dans les entrées utilisateur qu'il accepte?
la source
Réponses:
Bien sûr, vous avez tout à fait raison. Les programmes ne doivent jamais être «indulgents» car cela ne sert qu'à masquer les problèmes. Les problèmes doivent être mis en évidence et non balayés sous le tapis. Un message d'erreur informatif est un must absolu pour qu'un programme soit utile à l'utilisateur.
La plupart du temps, lorsque des données incorrectes / invalides sont fournies, le fournisseur de ces données (qu'il s'agisse d'un utilisateur ou de la sortie d'un autre programme) ne savait probablement pas qu'elles étaient invalides. Avaler l'erreur les gardera dans la conviction qu'elle est (ou pourrait être) valide, ce qui prolifère des données invalides.
La seule façon pour les systèmes d'interopérer est que cette interopération soit définie de manière complète et sans ambiguïté. Un programme qui accepte des données en dehors de la spécification fait que les données sont acceptées de facto même si elles ne sont pas valides par la spécification, ce qui non seulement rend la compatibilité une charge énorme plus difficile, mais signifie également qu'elle n'est plus définie officiellement. Le programme lui-même est désormais la norme de facto . Ainsi, les programmes indulgents sont impossibles à développer davantage ou à remplacer car vous ne pouvez pas apporter le moindre changement à son fonctionnement.
la source
Je pense que tout dépend de qui est votre cible démographique. Si ce sont des programmeurs, alors absolument pas. Votre programme devrait échouer et crier au meurtre sanglant. Cependant, si votre public cible n'est pas des programmeurs, votre programme doit être indulgent lorsqu'il peut gérer les exceptions avec élégance, sinon, chuchoter un meurtre sanglant.
Comme étude de cas, prenez le lecteur Flash NPAPI. Il existe une version "release" pour ceux qui ne se soucient pas vraiment de 99% des erreurs qui peuvent se produire, mais il existe également une version "debug" qui peut être utilisée pour crier un meurtre sanglant en cas de problème. Chacun prend en charge la lecture de contenu Flash bien sûr, mais est ciblé sur deux données démographiques complètement différentes.
Au final, je pense que l'important est: de quoi vos utilisateurs se soucient-ils?
la source
Il existe deux types de "clémence": l'un consiste à accepter une entrée incorrecte et à essayer de lui donner un sens, et l'autre consiste à accepter différents types d'entrée.
En général, vous voulez toujours le second quand c'est possible. Le premier, c'est quand tu meurs vite et fort. Un exemple: les dates.
Voici quelques exemples d'entrées, notamment valides, invalides et ambiguës.
2011-01-02
01/02/2011
Jan 2, 2011
2-Jan-2011
Green
Il n'y a qu'une seule entrée non valide ici:
Green
. N'essayez même pas de l'accepter comme date. Puisqu'il neGreen
s'agit évidemment pas d'une date, il s'agit d'un cas où l'échec silencieux est acceptable.01/02/2011
est valide, mais ambigu. Vous ne savez pas nécessairement si elle a été entrée comme date aux États-Unis (2 janvier) ou non (1 février). Ici, il est probablement préférable d'échouer bruyamment et de demander à l'utilisateur une date sans ambiguïté.2011-01-02
est généralement considéré comme sans ambiguïté, il est donc souvent bien d'aller de l'avant et de supposer que c'est le format "AAAA-MM-JJ", et d'échouer uniquement plus loin sur la ligne. C'est un peu un jugement, cependant, lorsqu'il s'agit de la saisie de l'utilisateur.Jan 2, 2011
et2-Jan-2011
sont valides et sans ambiguïté, ils doivent être acceptés. Cependant,The Second of January of the year 2011
est également valide et sans ambiguïté, mais aller aussi loin dans un souci de clémence est exagéré. Allez-y et échouez silencieusement, tout commeGreen
.En bref , la réponse est "cela dépend". Jetez un œil à ce qui peut être saisi et assurez-vous que vous n'acceptez jamais des types d'entrée conflictuels (comme
DD/MM/YYYY
vsMM/DD/YYYY
).Dans le contexte de la question / du commentaire lié , c'est un cas de
2011-01-02
. L'entrée ressemble à JSON et sera validée comme JSON même si le type MIME est incorrect; allez-y et essayez de l'utiliser même s'il échoue à un moment donné plus loin sur la ligne.la source
2011-01-02
,Jan 2, 2011
et2-Jan-2011
, si elle est pas trop difficile à mettre en œuvre), et non pas dans ce qu'elle génère . Les futurs clients de cette API n'ont même pas besoin d'en connaître un, tant qu'ils en saisissent correctement l'un. Idéalement, la couche API convertirait tout cela en la même représentation interne que le code utilise avant de le transmettre.2011-01-02
format, et c'est celui que vous mettriez dans votre documentation. Je ne vois aucun effet néfaste.Échouer en silence est la pire chose que vous puissiez faire, jamais. Avez-vous essayé de déboguer une API avec échec silencieux? C'est impossible .
Il y a "Faites de votre mieux pour récupérer mais envoyez une erreur détaillée" et il y a "Échec silencieux".
la source
Il me semble que la loi de Postel - "Soyez conservateur dans ce que vous faites, soyez libéral dans ce que vous acceptez des autres" est ce qui est discuté pour un service JSON. Ceci est généralement appliqué aux services Web et non à l'interface utilisateur.
Pour l'interface utilisateur, les commentaires constructifs et les entrées utilisateur contraignantes sont la règle de base que nous utilisons.
la source
Je pense que cela est bien couvert dans le chapitre 1, section 6 de TAOUP. Plus précisément, la règle de réparation , qui stipule qu'un programme doit faire ce qu'il peut avec une entrée, transmettre les données correctes et si la réponse correcte est un échec, le faire le plus tôt possible.
Un concept similaire est la programmation défensive . Vous ne savez pas quel type d'entrée vous recevrez, mais votre programme devrait être suffisamment robuste pour couvrir tous les cas. Cela signifie qu'il devrait être programmé dans les cas de récupération pour les problèmes connus comme l'entrée mutilée et un cas de capture pour gérer les inconnues.
Donc jeter entrée défectueuse est silencieusement bien, tant que vous êtes manipulez cette entrée. Vous ne devriez jamais le laisser tomber sur le sol, pour ainsi dire.
Pour une API, je pense que la clémence est la même que pour un programme. L'entrée est toujours incorrecte , mais vous essayez de réparer autant que possible. La différence est ce qui est considéré comme une réparation valide . Comme vous le faites remarquer, une API indulgente peut causer des problèmes car les gens utilisent des "fonctionnalités" qui n'existent pas.
Bien sûr, une API n'est qu'une version de niveau inférieur de la règle de composition . En tant que tel, il est vraiment couvert par la règle de la moindre surprise , car il s'agit d'une interface.
Comme le note la citation de Spencer, évitez les similitudes superficielles, qui peuvent être discutées à propos des entrées "floues". Dans ces conditions, je dirais normalement que tout indique que le programme est incapable de réparer, car il ne saura pas ce qui est souhaité, et c'est moins surprenant pour la base d'utilisateurs.
Cependant, vous avez affaire à des dates qui ont de nombreuses "normes". Parfois, ceux-ci sont même mélangés dans un seul programme (chaîne). Puisque vous savez qu'une date est attendue, tenter de reconnaître la date est juste une bonne conception. Surtout si la date provient d'un programme externe et est passée sans modification par une seconde sur son chemin vers vous.
la source
Les programmes déployés sur le serveur, la plupart du temps, sont censés accepter des milliers de demandes chaque minute, ou parfois chaque seconde. Si un programme serveur accepte et corrige les entrées défectueuses des clients, je crains qu'il n'ait 2 inconvénients:
Les programmes serveur ne doivent pas accepter les entrées défectueuses, mais les serveurs doivent renvoyer un message d'erreur au client, s'il y a une entrée défectueuse.
la source
Le comportement idéal, sur le plan conceptuel, est de faire ce qui peut être fait en toute sécurité, tout en s'assurant simultanément que quelqu'un qui peut résoudre les problèmes est en quelque sorte informé à leur sujet. Dans la pratique, bien sûr, cette dernière contrainte est souvent impossible à rencontrer directement, et il est donc préférable de traiter les intrants douteux.
Une chose qui peut être très utile dans la conception d'un protocole, d'une spécification de mise en forme ou d'un «langage» est d'avoir un moyen de distinguer quatre catégories d'éléments potentiels non compris:
Avoir une convention bien définie par laquelle les applications qui peuvent lire n'importe quelle version d'un format de données sera en mesure de reconnaître quelle catégorie est appropriée pour tout ce qui est généré conformément aux versions ultérieures est une bien meilleure approche que d'essayer de se faufiler dans des mesures de compatibilité ad hoc plus tard. Par exemple, si un format de fichier comporte des lignes de la forme "Tag: Value", on pourrait spécifier que le premier caractère de n'importe quelle balise indiquera la catégorie à laquelle il appartient; pour les balises des catégories silent-ignore, le premier caractère pourrait également indiquer la version de la norme pour laquelle la balise devrait être valide (de sorte que si une balise "silent-ignore" prétend être présente dans la version 3 de la norme, un analyseur pour la version l'ignorerait silencieusement, mais un analyseur pour la version 3 ou plus tard grincerait s'il ne pouvait pas l'analyser).
La chose la plus importante dans tous les cas est d'éviter de convertir des données ambiguës ou mal comprises en données erronées. Dans certains cas, il peut être préférable de refuser de propager des données ambiguës, mais dans d'autres cas, il peut être préférable de les propager précisément telles qu'elles ont été reçues au cas où le destinataire les considérerait comme non ambiguë. Ce qui est vraiment dangereux sinon carrément mal est la conversion de données en utilisant différentes hypothèses, par exemple la conversion d'une liste de dates comme:
dans une liste de dates comme
Même si l'on avait une liste avec quelques dates saisies de manière erronée, il peut être possible pour un être humain donné une liste dans le format d'origine de déterminer quel format était correct et de signaler des valeurs douteuses pour des recherches ultérieures (vérification par rapport à d'autres enregistrements, etc. ) Le rendu des dates dans ce dernier format, cependant, les brouillerait désespérément et de manière irrécupérable.
la source
Mon expérience de l'interface utilisateur provient principalement des systèmes de bureau. Les sites Web sont différents, bien que j'aie vu quelques sites qui pourraient contester un système de bureau. Mais pour ce que ça vaut:
J'ai trouvé que les messages d'erreur devraient être le tout dernier recours; un système idéal ne les aurait pas du tout. La meilleure chose à faire est de ne pas autoriser les mauvaises entrées en premier lieu: l'utilisateur ne peut pas entrer "vert" s'il sélectionne dans une liste déroulante de mois. Il ne peut pas appuyer sur un bouton grisé.
La prochaine meilleure chose à faire est d'accepter les mauvaises données. Supposons que vous affichez un histogramme des ventes quotidiennes pendant un mois. Après saisie par l'utilisateur, le graphique couvre un siècle et la barre un siècle plus tard est 10 fois plus élevée que les autres. L'utilisateur sait maintenant qu'il a fait quelque chose de mal et, en outre, en sait beaucoup plus sur ce qu'il a fait de mal que tout message pourrait lui dire. Lorsque l'entrée est graphique - en faisant glisser une souris, par exemple - ce type de rétroaction fonctionne toujours et est inestimable. Un certain nombre d'entrées peuvent être invalides, mais en utilisant cette méthode, l'utilisateur obtient une rétroaction instantanée et détaillée sur les résultats de chaque position de la souris.
Cela dit, l'utilisateur a parfois besoin de savoir pourquoi le bouton est grisé pour ne pas pouvoir le pousser. Ensuite , il n'y a aucune aide pour elle (s'il est , laissez - moi savoir) mais ungray le bouton et, quand il clique dessus, lui donner une bonne explication des raisons pour lesquelles le bouton ne fonctionne pas à l'heure actuelle.
la source
La déclaration concerne l'envoi d'informations sur Internet. L’envoi d’informations sur Internet a notamment pour conséquence qu’elles ne parviendront pas toujours à la cible ou qu’elles seront fragmentées.
la source
Quelque chose qui semble manquer ici - quelles sont les conséquences d'un échec?
Afficher une page Web? Vous devez faire tout votre possible pour tolérer une mauvaise saisie. Vos choix sont d'afficher ce que vous pouvez ou de lancer une erreur. Ce dernier cours ne donne rien à l'utilisateur et ne devrait donc être qu'un dernier recours car il donne à l'utilisateur un résultat complètement inutile, il serait assez difficile qu'une erreur soit pire que cela.
D'un autre côté, s'il demande la cible d'un Minuteman III, vous rejetez "Moscou" en entrée car il est potentiellement ambigu.
la source