Un tutoriel assez spécial pour mon retour. Je parlerais aujourd'hui d'une méthode de programmation, et de quelque chose de plutôt méconnu 
Plus jeune, quand je programmais, j'essayais de faire du code super propre, qui marche tout le temps. En cas de bug, blocage ou problème. Donc tests très rigoureux et corrections.
Seulement, ce n'est pas toujours possible de tester suffisamment, et c'est presque impossible, surtout sur des projets conséquents, de corriger tout. J'ai donc évolué pour adopter une autre approche : un code "idiot-proof", c'est-à-dire qui ne va pas "exploser" s'il y a un problème.
À éviter : les blocages (boucles infinies, threads interlockés), les leaks trop importants (création d'objet dans boucle, pointeurs perdus/mal détruits (C/C++), référence statiques non nettoyées ou inter-références (que le garbage collector n'aime pas du tout en Java), écriture sur adresse mémoire non initialisé, utilisation d'une fonction membre d'un objet non créé...
L'idée est d'avoir d'une part un code qui va reprendre la main dans la plupart des cas de bug non-bloquants (comme l'utilisation d'un objet non-initialisé), et d'écrire une partie du code de facon à éviter certains cas. Par exemple, j'ai utilisé une API qui décodait des chaines de caractères avec quelque chose comme ça:
CODE:
while (true)
{
if (str[iIndex] == ',')
{
break;
}
else if (str[iIndex] == 'A' || str[iIndex] == 'B' || str[iIndex] == 'C')
{
// Some code here
iIndex++;
}
}
Inconvénient, s'il existe un caractère autre que celui désiré (comme une fin de chaine), ca boucle à l'infini. En l'occurrence sur une création d'objet, donc crash sévère après un temps. Croyez le ou non, ce bug était tellement simple qu'il m'a fallu plus de 2 mois pour le trouver. Sortir le iIndex++ de la boucle permet déjà de faire mieux: ca risque simplement de lever une exception, lorsqu'on lira en dehors de la chaine.
Mais idéalement, il faut prévoir la fin de chaine, et tous cas inattendu. Je rajoute une gestion assez large des exceptions (pour exemple et par flemme, il vaudrait mieux mettre des exceptions concernant les éventuels problèmes du bloc, mais ça ne gène pas ici), car ce morceau de code n'est pas important par rapport au reste du programme et, donc, je ne veux pas qu'il plante mon programme en cas de problème :
CODE:
try{
while (str[iIndex] != EOF)
{
if (str[iIndex] == ',')
{
break;
}
else if (str[iIndex] == 'A' || str[iIndex] == 'B' || str[iIndex] == 'C')
{
// Some code here
}
else
{
theLog.add2Log("The letter " + str[iIndex] + " is not known by the parser.");
}
iIndex++;
}
}
catch (Exception e)
{
// Print something about the exception
}
C'est juste une facon de faire, pas forcément optimale, mais qui peut minimiser les problèmes ! Pour résumer le principe : "J'assume que je peux faire des bétises, donc j'écris mon code pour y résister"
. L'idée est que les portions de codes bien écrites, mais idiot-proof, vont amortir les problèmes des portions buggées et, si possible, me donner des indications me permettant de corriger ces portions ! Bien sûr ça ne marche pas toujours, malheureusement.
Commentaires