Je réfléchis à ce problème depuis un certain temps et je serais curieux d'avoir des opinions d'autres développeurs.
J'ai tendance à avoir un style de programmation très défensif. Mon bloc ou méthode typique ressemble à ceci:
T foo(par1, par2, par3, ...)
{
// Check that all parameters are correct, return undefined (null)
// or throw exception if this is not the case.
// Compute and (possibly) return result.
}
De plus, pendant le calcul, je vérifie tous les pointeurs avant de les déréférencer. Mon idée est que, s'il y a un bug et qu'un pointeur NULL devrait apparaître quelque part, mon programme devrait gérer cela correctement et refuser simplement de continuer le calcul. Bien sûr, il peut signaler le problème avec un message d'erreur dans le journal ou un autre mécanisme.
Pour le dire de manière plus abstraite, mon approche est
if all input is OK --> compute result
else --> do not compute result, notify problem
D'autres développeurs, dont certains de mes collègues, utilisent une autre stratégie. Par exemple, ils ne vérifient pas les pointeurs. Ils supposent qu'un morceau de code doit recevoir une entrée correcte et qu'il ne devrait pas être responsable de ce qui se passe si l'entrée est incorrecte. De plus, si une exception de pointeur NULL plante le programme, un bogue sera trouvé plus facilement pendant les tests et aura plus de chances d'être corrigé.
Ma réponse est normalement: mais que se passe-t-il si le bogue n'est pas trouvé pendant les tests et apparaît lorsque le produit est déjà utilisé par le client? Quelle est la meilleure façon pour le bogue de se manifester? Doit-il s'agir d'un programme qui n'exécute pas une certaine action, mais qui peut continuer à fonctionner, ou d'un programme qui se bloque et doit être redémarré?
Résumer
Laquelle des deux approches pour gérer les entrées erronées conseilleriez-vous?
Inconsistent input --> no action + notification
ou
Inconsistent input --> undefined behaviour or crash
Éditer
Merci pour les réponses et suggestions. Je suis aussi fan de design par contrat. Mais même si je fais confiance à la personne qui a écrit le code appelant mes méthodes (c'est peut-être moi-même), il peut toujours y avoir des bugs, conduisant à une mauvaise saisie. Mon approche consiste donc à ne jamais supposer qu'une méthode a été correctement saisie.
De plus, j'utiliserais un mécanisme pour attraper le problème et en informer. Sur un système de développement, il ouvrirait par exemple une boîte de dialogue pour avertir l'utilisateur. Dans un système de production, il suffit d'écrire quelques informations dans le journal. Je ne pense pas que des vérifications supplémentaires puissent entraîner des problèmes de performances. Je ne sais pas si les affirmations sont suffisantes, si elles sont désactivées dans un système de production: peut-être qu'une situation se produira dans une production qui ne s'était pas produite pendant les tests.
Quoi qu'il en soit, j'ai été vraiment surpris que de nombreuses personnes suivent l'approche opposée: elles laissent l'application se planter "à dessein" car elles soutiennent que cela facilitera la recherche de bogues pendant les tests.