Clés techniques et clés d’état

19 09 2006

update: remarques en fin d’article

Je suis partisan d’une simplification des tables avec une clé primaire non métier. Ce que l’on nomme généralement clé primaire technique sous forme d’un entier auto-incrementé, c’est mon coté rails qui parle là.

Mais concernant la définition des états je desteste me retrouver avec des entiers de 1 à X décrivant chacun une étape. Exemple :

1 -> Initialisation 2 -> En cours 3 -> Fin traitement OK 4 -> Fin traitement KO 5 -> Stockage 6 -> Sortie

Le gros problème de ce genre d’états est qu’il difficile pour l’esprit humain de garder la correspondance en tête. Surtout quand on se retrouve avec une dizaine de listes différentes comme ceci.

Si l’on prend des données lambda en base utilisant le système précédent, voici ce que l’on pourrait voir dans la base de données :

|   DONNEE  |   ETAT  | |===========|=========| |  entree1  |    1    | |  entree2  |    3    | |  entree3  |    5    | |  entree4  |    2    |

Résultat, on passe son temps à se demander quelle est déjà l’étape correspondante. J’aimerais avoir une façon plus lisible de comprendre ces éléments sans devoir me référer à une autre table ou retrouver dans mon code les différentes implémentations.

Par exemple je trouve ceci plus lisible :

|   DONNEE  |   ETAT  | |===========|=========| |  entree1  |  INIT   | |  entree2  |  T OK   | |  entree3  |  T KO   | |  entree4  |  ENCO   |

Mais j’ai bien conscience que d’une part ce n’est peut-être pas vraiment optimisé car on passe d’une colonne d’entiers à une colonne de caractères (Problème d’index et compagnie) et d’autre part, ca fait un peu charabia cet état sur 4 caractères.

D’autres propositions ?

update: Suite aux commentaires éclairés de Yann (Pas de blog à linker…bientôt ?), je crois que ma refléxion part d’un postulat incorrect. En effet, je base ma réflexion sur un existant où l’on retrouve dans une table des états de 1 à 6. Ces états ne sont pas des clés étrangères pointant vers une table de référence des états et je crois que mon erreur vient de là. Je cherche à résoudre un problème qui n’est pas, et sa résolution est seulement l’affaire d’un travail d’amélioration de la base de données existante.



Guide pour la gestion des exceptions

30 08 2006

Cet article marche pour tout langage objet, mes lecteurs ruby, .net, java et php peuvent donc lire 😉 . Je ne parlerais ici que des exceptions non checkés car ce sont aujourd’hui les exceptions les plus répandues (et les checkés n’existent pas en .net…)

La gestion des exceptions est problématique c’est un fait. Qu’on soit développeur débutant ou confirmé, au moment de traiter une exception on se pose toujours les mêmes questions :

  • Est-ce que je l’attrape ou je la laisse remonter ?
  • Qu’est ce que je met dans le finally ?
  • Est-ce que je l’encapsule ?

Évidemment comme tout problème complexe, il n’y a pas de réponse définitive et tout est question de contexte. Pour ma part, j’applique une méthode qui, à défaut d’être complète, me permet d’évaluer rapidement dans quel contexte je suis et de décider de la solution à apporter.

1. Algorithme de décision

La première question que je me pose lors de l’appel d’un code qui risque de lever une exception est : Qu’est-ce que mon programme doit faire si l’exception arrive ?

La réponse à cette question tombera toujours dans deux catégories :

* J’ai une réponse de substitution et le programme peut continuer.

Par exemple, si j’ai une exception lors de la génération d’une couleur, j’ai prévu dans les spécifications de prendre une couleur par défaut. Dans ce cas, on pourra écrire ceci :

try {  couleur = GenerationCouleur() } catch( GenException ) {   couleur = CouleurParDefaut }

Attention dans ce cas à n’attraper que l’exception dont j’avais prévu la substitution et non un vilain catch( Exception ).

* Je n’ai pas de reprise particulière au problème.

L’exemple le plus commun est un plantage de l’accès à la base de données. Si je suis en train d’enregistrer un nouvel utilisateur et que mon accès sql se met en vrac, il est évident que je n’aurais aucun moyen de contournement pour terminer correctement mon action.

L’idée est donc d’admettre qu’on ne peut rien faire et de laisser remonter l’exception. De cette façon, l’exception va remonter les couches d’appels jusqu’à un appelant qui lui aura une réponse à apporter. Dans le cas d’une application web, il est commun que le seul qui aura une réponse à apporter sera le conteneur web (la brique la plus haute) qui affichera une jolie page d’erreur et s’occupera de logger tout ça…

2. Rethrow

Un autre type de code que l’on voit souvent :

try {   ... } catch( Exception ex) }    throw new MonException(ex) }

Ma prise de position sur ce sujet est qu’il faut éviter de catcher pour rien. En effet, quelle est la valeur ajoutée par la ligne ci-dessus ?

Cela ne fait qu’ajouter une indirection dans la cause réelle de l’erreur et provoque donc plus de travail pour le développeur qui doit comprendre ce qui s’est passé. Des stacktraces de 3 kms de long ne sont jamais agréables à lire…

La seule exception (je ne sais pas si le mot est bien choisi) est le développement d’un librairie ou d’un composant tiers. Dans ce cas effectivement, il sera plus propre de cacher les exceptions internes avec des jolis exceptions car la séparation est claire.

3. Fail fast

L’argument en faveur d’un ciblage précis des exceptions à attraper est le fail fast. L’idée du Fail fast est de provoquer un plantage quand une exception incontrôlée survient dans le but d’assainir le programme. En effet, il arrive souvent qu’on soit tenté d’avaler les exceptions avec du joli code comme ceci :

try {   ... } catch( Exception ) { // Toutes les exceptions  // on ne fait rien. On AVALE }

Et bien c’est MAL ! En effet, sur le moment effectivement si une erreur survient le client est content car son application n’affiche pas d’erreur et il peut continuer en apparence. Mais en réalité, le programme vient de basculer dans un état incohérent où l’état des objets en mémoire n’est plus garantie.

Résultat, on se retrouve avec un client qui se plaint d’avoir un message d’erreur 3 pages plus loin et alors là vient le courageux développeur qui va mettre 2 jours à comprendre le pourquoi du comment de l’erreur !

Dans le paradis du Fail Fast, le client serait tombé directement sur une page d’erreur au premier coup, il aurait pris son téléphone pour gueuler (dans les 2 cas il gueule car ça ne marche pas de toute façon 🙂 ) et hop corrigé en 15 mins, car effectivement c’était une mauvaise idée de caster cet objet de classe Personne en classe Agenda… (On sent le vécu)

4. Et le legacy ?

Le fail fast est une bonne idée sur les nouveaux développements mais que peut-on faire sur sur un applicatif existant -legacy- miné d’avaleuses (ne cherchez pas à visualiser) ?

Une mauvaise idée serait d’enlever tous les catchs {} vides car le client se retrouverait avec des erreurs sur des parties qui marchaient auparavant et ne comprendrait pas en quoi c’est mieux qu’avant. Ma proposition est plutôt d’ajouter dans tous les catchs un simple log. Par exemple :

catch (Exception ex) {   log.error(ex) }

Ainsi on pourra surveiller le comportemant du legacy et detecter les points d’erreurs qui n’étaient pas visibles avant. L’objectif étant évidemment de corriger le source au fur et à mesure de la détection de ces erreurs. Concernant les évolutions du programme, aucune pitié, on fail fast !

5. Conclusion

Le tour des rapide mais j’espère qu’il servira à enlever quelques ambiguités sur la réflexion que l’on porte aux exceptions.

Comme le sujet porte à débat, j’espère avoir des jolis commentaires sur ce post 🙂



La Toolbox du développeur

25 08 2006

La productivité est un saint-graal pour tout développeur.

En dehors du fanatisme classique qui consiste à vouloir tout tester et toujours en dernière version (vive les versions beta), il peut tout de même être intéressant de se constituer une Toolbox sérieuse et pratique.

J’ai donc pris l’habitude au fil du temps de me monter une Toolbox ou boite à outils en bon francais.

Je vois trop souvent des développeurs se contenter des outils standards fournis avec l’OS pour travailler en dehors de l’IDE. Un exemple flagrant est l’éditeur de texte Notepad. Cet outil est dépassé depuis longtemps.

Notepad2 pour le même prix (c’est à dire gratuit) offre la prise en compte des CL/RF (les retours chariot), la colorisation suivant le format, la prise en compte complète de l’encoding, etc.

La référence du genre est la Scott Hanselman’s 2005 Ultimate Developer and Power Users Tool List. Cette liste est fortement orientée pour les développeurs .NET mais on y retrouve Notepad2 qui est pratique pour tous.

Si vous voulez avancer plus loin dans le sujet, Wrox offre sur son site web des vidéos  »toujours de Scott Hanselman » qui nous montre ses nombreux secrets de productivité et d’outils. On peut le voir en action et c’est impressionnant. C’est un « tueur » dans son genre et malgré ma relative longue expérience sur les environnements Windows, j’ai appris des nouvelles commandes sous la console MS-DOS !

Bonne chasse aux outils !

Update : C’est tout chaud : Scott Hanselman’s 2006 Ultimate Developer and Power Users Tool List for Windows et c’est toujours aussi intéressant…



Nouveau blog technique à suivre : Le Danois

22 08 2006

Je suis ravi de constater que mon danois préféré (non ce n’est pas AQUA !) revient sur la blogging-scene après quelques mois d’absence.

Qui dit retour de nos jours dit 2.0 et il n’échappe pas à la règle. Rassurez vous, il ne revient pas en version Bêta 😉 .

Il y parle technologies de l’informatique et nouveautés du Web avec une grande ouverture d’esprit et un avis juste et souvent pertinent.

Le Danois 2.0

A vos flux. (comment on dit bookmarker en RSS?)



Software Factory (Usine logicielle) : Batterie de poulets ?

3 08 2006

Il est étonnant et même navrant de voir à quel point le CEO de 6th sense a pu se méprendre dans l’intérêt que prend aujourd’hui les softwares factories.

the software factory is as outdated as Henry Ford’s Model T assembly line … crush the flexibility and creativity needed to build software and meet constantly changing requirements.

L’usine logicielle est aussi périmé que le fordisme…. elle abolit la flexibilité et la créativité nécéssaire au développement et au changement permanent

developers get plugged into an assembly line and are treated like battery chickens expected to squeeze our code.

Là c’est trop gros, je ne traduis même plus :-).

On peut constater que l’auteur n’a vraiment rien compris au principe de l’usine logicielle.

Pour rétablir un peu de vérité, l’intérêt de mettre en place une software factory c’est justement de libérer le développeur de certains tâches répétitives et contraignantes et donc de lui laisser plus de temps à la réflexion et à la créativité sur ses solutions.

On a vraiment l’impression que l’auteur s’est contenté de traduire littéralement le terme software factory et a pris peur tout seul 😉 .

vu sur serverside.



Pousser le changement

26 07 2006

Dans le livre Peopleware, le chapitre « Making change possible » parle de la difficulté à faire changer les choses dans un projet (aspect aussi bien technique que méthdologique).

J’ai à plusieurs reprises travaillé avec des équipes ayant un niveau de technicité différent.Par exemple, des équipes travaillant sans un gestionnaire de sources.

Ma première réaction est l’étonnement :

Mais comment pouvez vous travailler avec des conditions pareilles ?

(Si l’on y réfléchit, on peut très bien travailler sans gestionnaire de conf, il suffit de faire plus attention c’est tout 😉 ).

Passé cette réaction, la prochaine étape est de montrer à l’équipe l’intérêt de cet outil et leur faire intégrer dans leur process de développement.

Pour cela, j’avais tendance à donner l’ensemble des avantages, dire que tout sera plus beau et bien mieux. Ce qu’on peut représenter par le schéma suivant :

 ANCIENNE FACON ==> NOUVELLE FACON

Et bien, cette technique en pratique donne de mauvais résultats (incroyable c’est le sujet de ce post)…

Par exemple, la mise en place des projets sur le gestionnaire est difficile au début, des nouveaux mots sont à maitriser pour comprendre. La syntaxe n’est pas évidente non plus et les erreurs sont fréquentes. Résultat, on passe beaucoup plus de temps à gérer ses sources, temps qui était disponible auparavant pour d’autre chose…

Au final, la réalité s’approche plutôt du schéma suivant :

 ANCIENNE FACON ==> CHAOS ==> APPRENTISSAGE ==> NOUVELLE FACON

Le passage obligé mais souvent oublié c’est l’étape chaotique où les développeurs râlent car cette nouvelle complexité ne leur apporte aucun avantage. Ils ne voient que les défauts et aucun intérêt… Cette étape difficile est souvent le moment où se repose la question cruciale :

Est-ce que vraiment ca valait le coup, parce qu’on peut encore revenir en arrière sinon !

Finalement avec un peu de volonté et de la pratique, tout le monde finit par piger le truc et cette nouvelle façon de travailler plaît !

La leçon à retenir c’est que lors d’un changement, il faut être très clair sur plusieurs points :

  • Oui ça sera mieux (on y croit)

MAIS

  • Il y aura une période incertaine et plus difficile dont il ne faut pas avoir peur
  • Il faut accepter de sortir de notre sécurité actuelle pour tenter de nouvelles choses
  • Le changement ne doit pas être un couteau sous la gorge et il faut avoir le droit à l’erreur


Virtual PC gratuit en téléchargement

13 07 2006

Après la version Virtual Serveur, déjà offerte depuis un petit moment, la version « normale » devient gratuite à son tour.

La virtualisation devient plus que jamais une commodité et l’on peut constater que tous les acteurs ont maintenant leur version gratuite (Microsoft, VMWare…)

Pour Microsoft, c’est une stratégie intéressante qui leur permettra de vendre des licences serveur sur lesquels seront installé les machines virtuelles. Puisque évidemment, Virtual PC et Virtual Server ne fonctionnent tous deux que sur un OS Windows.

De plus, si l’OS hôte est un Windows, cela pourra encourager les administrateurs système à installer également des windows dans les machines virtuelles. Conclusion, je pense qu’ils ont refléchi à deux fois avant d’offrir gratuitement cet outil 🙂

En dehors de cet aspect serveur, il est plus que jamais interessant pour les développeurs d’avoir également des machines virtuelles afin de tester différents environnements. Par exemple, un environnement dotNET, un Java, un Ruby 😉 … ou pour tester différents OS/navigateurs web…

Lien pour télécharger Virtual PC 2004.