Mon professeur ne cesse de se référer à cet exemple Java lorsqu'il parle de code "robuste":
if (var == true) {
...
} else if (var == false) {
...
} else {
...
}
Il affirme que "code robuste" signifie que votre programme prend en compte toutes les possibilités et qu'il n'existe pas d'erreur - toutes les situations sont gérées par le code et résultent en un état valide, d'où le "else".
Je suis douteux, cependant. Si la variable est un booléen, à quoi sert-il de vérifier un troisième état lorsqu'un troisième état est logiquement impossible?
"Ne pas avoir d'erreur" semble également ridicule; même les applications Google montrent les erreurs directement à l'utilisateur au lieu de les avaler en silence ou de les considérer comme un état valide. Et c'est bien - j'aime savoir quand quelque chose ne va pas. Et il semble tout à fait la prétention de dire qu'une application n'aurait jamais d'erreur.
Alors, quelle est la définition réelle de "code robuste"?
la source
Réponses:
Qu'en est-il d'un
Boolean?
qui permet unNULL
état qui n'est ni vrai ni faux. Maintenant que doit faire le logiciel? Certains logiciels doivent être très résistants aux chocs, comme les stimulateurs cardiaques. Vous avez déjà vu quelqu'un ajouter une colonne à une base de donnéesBoolean
et initialiser les données actuellesNULL
? Je sais que je l'ai vu.Voici quelques liens qui expliquent ce que signifie être robuste en termes de logiciel:
Si vous pensez qu'il existe une définition universellement acceptée de «robuste» ici, bonne chance. Il peut y avoir des synonymes comme anti-bombes ou anti-imbéciles. Le programmateur de bandes magnétiques est un exemple de quelqu'un qui écrit habituellement du code robuste, du moins dans ma compréhension des termes.
la source
Pour les besoins de ma discussion, un Bool peut avoir 2 états, True ou False. Tout le reste n'est pas conforme à la spécification de programmation Langugae. Si votre chaîne d’outils n’est pas conforme à ses spécifications, vous êtes blessé, peu importe ce que vous faites. Si un développeur crée un type de Bool comportant plus de 2 états, c'est la dernière chose qu'il ferait dans ma base de code.
Option A.
Option B
J'affirme que l'option B est plus robuste .....
Tout twit peut vous dire de gérer les erreurs inattendues. Ils sont généralement faciles à détecter une fois que vous y pensez. L'exemple que votre professeur a donné n'est pas quelque chose qui pourrait arriver, c'est donc un très mauvais exemple.
A est impossible à tester sans harnais de test compliqués. Si vous ne pouvez pas le créer, comment allez-vous le tester? Si vous n'avez pas testé le code, comment savez-vous que cela fonctionne? Si vous ne savez pas que cela fonctionne, vous n’écrivez pas un logiciel robuste. Je pense qu'ils appellent encore cela un Catch22 (excellent film, regardez-le un jour).
L'option B est simple à tester.
Problème suivant, posez cette question à votre professeur: "Que voulez-vous que je fasse à ce sujet si un booléen n’est ni vrai ni faux?" Cela devrait mener à une discussion très intéressante .....
Dans la plupart des cas, un dépotoir est approprié, au pire, il gêne l'utilisateur ou coûte très cher. Que faire si, par exemple, le module est le système de calcul de la rentrée en temps réel de la navette spatiale? Toute réponse, aussi inexacte soit-elle, ne peut être pire que d’annuler, ce qui tuerait les utilisateurs. Alors que faire, si vous savez que la réponse peut être fausse, optez pour le 50/50, ou abandonnez et tentez l'échec à 100%. Si j'étais un membre de l'équipage, je prendrais le 50/50.
L'option A me tue L'option B me donne une chance égale de survie.
Mais attendez - c'est une simulation de la rentrée dans la navette spatiale - alors quoi? Abort pour que tu saches. Cela vous semble une bonne idée? - NON - parce que vous devez tester avec le code que vous prévoyez d'expédier.
L'option A est préférable pour la simulation, mais ne peut pas être déployée. C'est inutile L'option B étant le code déployé, la simulation fonctionne de la même manière que les systèmes en direct.
Disons que c'était une préoccupation valable. La meilleure solution serait d'isoler le traitement des erreurs de la logique d'application.
Lecture ultérieure - machine à rayons X Therac-25, échec de la fusée Ariane 5 et autres (Link a beaucoup de liens cassés mais suffisamment d’informations pour que Google puisse vous aider)
la source
if (var != true || var != false) {
devrait&&
plutôt être un code .En réalité, votre code n’est pas plus robuste mais MOINS robuste. La finale
else
est simplement un code mort que vous ne pouvez pas tester.Dans les logiciels critiques tels que les vaisseaux spatiaux, le code mort et, plus généralement, le code non testé sont interdits: si un rayon cosmique perturbe un seul événement et que votre code mort est activé, tout est possible. Si le SEU active une partie du code robuste, le comportement (inattendu) reste sous contrôle.
la source
Je pense que le professeur pourrait être déroutant "erreur" et "bug". Le code robuste devrait certainement avoir peu / pas de bugs. Un code robuste peut, et dans un environnement hostile, avoir une bonne gestion des erreurs (qu'il s'agisse de la gestion des exceptions ou des tests de statut de retour rigoureux).
Je conviens que l'exemple de code du professeur est ridicule, mais pas aussi ridicule que le mien.
la source
boolean x = something(); if (x) { x = True // make sure it's really true, ... }
Il n'y a pas de définition convenue du code robuste , car pour beaucoup d'éléments de programmation, c'est plus ou moins subjectif ...
L’exemple donné par votre professeur dépend de la langue:
Boolean
peut êtreTrue
ouFalse
, il n'y a pas de troisième optionbool
peut êtretrue
,false
ou (malheureusement) provient d'une distribution douteuse qui le met dans un cas inconnu ... Cela ne devrait pas arriver, mais peut, à la suite d'une erreur précédente.Cependant, les recommandations de votre professeur occultent le code en introduisant une logique superflue pour les événements à ne pas se produire au milieu du programme principal. Je vous orienterai donc plutôt vers la programmation défensive .
Dans le cas d'une université, vous pouvez même l'augmenter en adoptant une stratégie de conception par contrat:
size
est le nombre d'éléments dans ladata
liste)a
est inférieure à10
)Exemple:
la source
L'approche de votre professeur est totalement erronée.
Une fonction, ou juste un peu de code, devrait avoir une spécification qui dit ce qu’elle fait, qui devrait couvrir toutes les entrées possibles. Et le code doit être écrit de manière à ce que son comportement corresponde à la spécification. Dans l'exemple, j'écrirais la spécification assez simple comme ceci:
Ensuite, vous écrivez la fonction:
et le code répond à la spéc. Alors votre professeur dit: Et si var == 42? Regardez la spécification: il est dit que la fonction doit faire "ça". Regardez le code: la fonction fait "ça". La fonction répond à la spéc.
Là où le code de votre professeur rend les choses totalement douteuses, c'est qu'avec son approche, quand var n'est ni vrai ni faux, il exécute un code qui n'avait jamais été appelé auparavant et qui n'a absolument pas été testé, avec des résultats totalement imprévisibles.
la source
Je suis d 'accord avec la déclaration de @ gnasher729: l' approche de votre professeur est totalement erronée.
Robuste signifie qu'il est résistant aux ruptures / défaillances car il fait peu d'hypothèses et est découplé: il est autonome, se définit et est portable. Cela implique également d'être adaptable à l'évolution des besoins. En un mot, votre code est durable .
Cela se traduit généralement par des fonctions courtes récupérant leurs données à partir de paramètres transmis par l'appelant et par l'utilisation d'interfaces publiques pour les consommateurs (méthodes abstraites, wrappers, indirection, interfaces de style COM, etc.) plutôt que par des fonctions contenant un code d'implémentation concret.
la source
Le code robuste est simplement un code qui gère bien les échecs. Ni plus ni moins.
Parmi les types d'échec, il en existe de nombreux types: code incorrect, code incomplet, valeurs inattendues, états inattendus, exceptions, épuisement des ressources, ... Le code robuste les gère bien.
la source
Je considérerais le code que vous avez donné comme exemple de programmation défensive (du moins si j'utilise le terme). Une partie de la programmation défensive consiste à faire des choix qui minimisent les suppositions faites sur le comportement du reste du système. Par exemple, lequel de ces choix est le meilleur:
Ou:
(Si vous avez du mal à voir la différence, vérifiez le test de boucle: le premier utilise
!=
, le second utilise<
).Maintenant, dans la plupart des cas, les deux boucles se comporteront exactement de la même manière. Cependant, la première (comparaison avec
!=
) fait une hypothèse quii
ne sera incrémentée qu’une fois par itération. Si la valeursequence.length()
est ignorée, la boucle peut continuer au-delà des limites de la séquence et provoquer une erreur.Vous pouvez donc faire valoir que la deuxième implémentation est plus robuste: elle ne dépend pas d'hypothèses sur le fait que le corps de la boucle change
i
(remarque: en fait, l'hypothèsei
n'est jamais négative).Pour vous motiver à ne pas faire cette hypothèse, imaginez que la boucle balaye une chaîne et effectue un traitement de texte. Vous écrivez la boucle et tout va bien. Maintenant que vos exigences changent et que vous décidez que vous devez prendre en charge les caractères d'échappement dans la chaîne de texte, vous modifiez le corps de la boucle de sorte que, si elle détecte un caractère d'échappement (par exemple, une barre oblique inversée), elle s'incrémente
i
pour ignorer le caractère immédiatement après l'échappement. Maintenant, la première boucle a un bogue car si le dernier caractère du texte est une barre oblique inverse, le corps de la boucle sera incrémentéi
et la boucle continuera au-delà de la fin de la séquence.la source
Personnellement, je décris un code comme 'robuste' qui a celui-ci, attributs importants:
Maintenant, par pause, je veux dire soit que le système soit dans un état instable, soit qu’il provoque une exception UNHANDLED . Vous savez, parfois pour un concept simple, vous pouvez faire une définition et une explication complexes. Mais je préférerais des définitions simples. Les utilisateurs savent assez bien trouver des applications robustes. Si l'utilisateur de votre application vous envoie de nombreuses demandes concernant des bogues, une perte d'état, des flux de travail non intuitifs, etc., il y a un problème avec votre programmation.
la source