Christophe Le Bot

  • Navigation rapide
Pratique de la conception numérique

Derniers commentaires

  • Test d’interface : paiement d’amendes en ligne
    • Rovellotti Olivier | Ce site est un véritable cauchemar UX Excellent article http://www.natural-solutions.e u/
    • Julien | Pour info, mon e-numero etait sur le cote gauche, ecrit verticalement, sans aucun label.
  • Agence web ou SSII : que choisir ?
    • Rovellotti Olivier | La limite n’est plus aussi claire qu’avant effectivement et les différence de prix sont du l’ordre du *10. Généralement les équipes dans les agences sont plus...
  • Une excellente thèse sur Simile Exhibit
    • Olivier Rossel | Bonjour. Malgre les annees, avez vous toujours en memoire vos usages d’Exhibit? Je serais ravi d’en discuter avec vous. Cordialement, Olivier Rossel.
  • Utiliser le planificateur de tâches OVH (crontab) avec PHP
    • Max | Bonjour, comme faire pour appeler une version de PHP qui n’est plus proposée par défaut dans le manager ? J’essaie de lancer un cron avec php 5.3 mais le log affiche No such file...
 

Archives de la catégorie
Bonnes pratiques

Du bon usage des exceptions

Si nous intégrons tous la gestion des exceptions dans notre code source (enfin, je l’espère…), en faisons-nous vraiment bon usage ? Entre les « maniaco-dépressifs » qui en mettent partout et les « bricolo-codeurs » qui savent à peine les mettre en place, il y a un compromis… qui n’est pas toujours évident à trouver.

Erreur, dysfonctionnement et exception

Par définition, une exception n’est levée qu’en cas d’état exceptionnel de l’application. Le tout est d’arriver à définir l’état d’exception. Est-ce un dysfonctionnement applicatif grave (connexion à une base de données qui tombe, fichier applicatif introuvable, allocation mémoire excessive, objet corrompu) ? Est-ce un fonctionnement normal mais exceptionnel (erreur d’authentification utilisateur, données entrantes non conformes) ? Est-ce une situation fréquente mais ne répondant pas au scénario optimal d’utilisation (mauvaise utilisation de l’application, erreurs de saisie d’un utilisateur) ?

Après avoir vu tous les cas sur le terrain, mais aussi dans des documents de référence, j’avoue ne plus savoir où placer le curseur…

Réserver l’exception aux dysfonctionnements

Pour ma part, je préfère garder l’exception pour les situations les plus rares et les plus graves, ce que je définis comme des situations exceptionnelles. Elles sont généralement dues à des dysfonctionnements de l’application, c’est-à-dire des états qui n’ont pas été prévus dans les séquences d’utilisation.

Sur ce principe, une erreur de saisie d’un utilisateur ne devrait jamais déclencher une exception lorsque sa valeur est contrôlée par l’application. Si j’entre une adresse e-mail invalide dans un formulaire, l’application traitera l’événement comme une erreur utilisateur et non comme un dysfonctionnement interne. Elle retournera le formulaire avec un joli message d’erreur… qui n’a rien d’exceptionnel puisque ce traitement fait partie du fonctionnement normal de l’application (mais pas de sa séquence nominal !). Même si cela semble évident (pour moi, du moins…), l’utilisation des exceptions pour ces cas est loin d’être anecdotique.

Bien sûr, si après validation de l’adresse e-mail l’application ne peut pas traiter normalement le formulaire, l’utilisation des exceptions permettra de trouver l’origine du dysfonctionnement, sans mettre les données dans un état inconsistant.

Trouver le bon équilibre

Dans le cas d’applications complexes où la modularité de code est de rigueur (genre « full MVC avec intégration de tous les designs patterns du GoF » !), savoir instancier puis récupérer une exception au meilleur endroit (ou moment pour les aficionados de la programmation événementiel) est déjà moins évident. Quels rôles jouent les différents niveaux de la partie M (modèle) ? Comment réagit la partie C (contrôleur) ? Comment gérer efficacement l’imbrication des exceptions (du noyau à l’interface en passant par les couches métiers) sans perturber la compréhension du problème par l’utilisateur ? Bien sûr, chaque cas est particulier, mais j’avoue que je souhaiterais bien discuter du sujet, autour de vos expériences.

Je vous passe la main !

Cryptage MD5 réversible ? Indirectement, oui !

Le cryptage de mots de passe par MD5 est sans doute la mesure de sécurité la plus utilisée par les développeurs. Son intérêt : crypter une chaîne de caractères, sans avoir la possibilité mathématique de faire l’opération inverse. Enfin presque…

Depuis 2004, on sait que MD5 n’est plus très sûr. Cependant, casser cet algorithme n’est pas à la portée de tout le monde. Aucun risque pour vos bases de données utilisateurs ? C’est sans compter sur les bases de hash MD5. Leur but : stocker des chaînes de caractères et leur hash. Comme les utilisateurs entrent souvent des mots communs ou connus, il est très simple d’interroger ces bases pour obtenir la liste des chaînes de caractères compatibles avec un hash MD5. GData en est un exemple particulièrement efficace et complet.

Vous voulez connaître le mot de passe caché derrière le hash MD5 fe01ce2a7fbac8fafaed7c982a04e229 ? Le voici en 1/10e de seconde : demo. Et celui-ci, assez fréquent dans les bases mal paramétrées : 21232f297a57a5a743894a0e4a801fc3. C’est admin !

Il est temps de changer de méthode de cryptage…

Source : Nexen

Le développement agile transforme le monde des affaires

Agile Development sur CNN Money

Etrange surprise que de voir le développement agile à la 18e place du classement Business 2.0 de CNN Money. Alors que la plupart des équipes informatiques ne comprennent pas encore pourquoi, ni comment de telles méthodes de gestion de projets apportent des résultats, voilà qu’elles deviennent un des 50 piliers de la profonde transformation du monde des affaires.

C’est oublier un peu vite qu’un bon business man est avant tout visionnaire…

Source : Scrum – Méthodes agiles

Utiliser les catégories pour gérer les tags sous WordPress

Logo WordPress

Incroyable mais vrai : WordPress ne gère pas les tags ! Ces petites étiquettes qui donnent du sens au contenu généré par les utilisateurs, sont dans tous les services estampillés « Web 2.0″… sauf dans WordPress. Les utilisateurs râlent depuis longtemps : c’est qu’ils les demandent, ces tags ! Et avec insistance ! Ils devaient être intégrés dans la prochaine version (la v.2.2 à paraître ces jours-ci) et ne le seront que dans la version 2.3. Les plus impatients ont déjà migré sur d’autres plates-formes…

Mais au fait, a-t-on vraiment besoin des tags dans WordPress ?

Non, car ce moteur de blog propose les catégories pour les gérer. Certains vont tout de suite me dire qu’il y a une grosse différence entre les deux et qu’il faut donc les deux. C’est vrai, il y a une telle différence que j’utilise les deux dans ce blog… en m’appuyant seulement sur les catégories.

Gérer les catégories comme un arbre sémantique

L’astuce consiste à utiliser la hiérarchie des catégories comme un arbre sémantique. Ensuite, il suffit de placer certains de ses noeuds dans l’interface. Pour illustrer le principe, je vais prendre l’exemple de ce blog qui utilise à la fois des thèmes et des tags.

Etape 1 : créer les racines

Pour commencer, je crée les catégories qui me serviront de racines :

  • Thèmes
    Pour gérer une classification hiérarchique.
  • Mots-clés
    Pour gérer les tags.

WordPress m’indique les identifiants des deux racines : 3 pour Thèmes et 4 pour Mot-clés. Ces identifiants sont importants pour placer les racines dans l’interface. Leur valeur dépend bien sûr de votre propre installation de WordPress. Mais n’allons pas trop vite…

Etape 2 : créer les thèmes

Mes thèmes sont hiérarchiques. Je crée donc les thèmes principaux (Concevoir, Développer, Exploiter, Imaginer, Savoir) en les plaçant sous la catégorie Thèmes. Puis, viennent les thèmes secondaires placés chacun sous un thème principal. Rien de très compliqué, c’est du WordPress basique !

Thèmes sous WordPress
La liste de mes thèmes dans l’interface de WordPress.

Etape 3 : afficher les thèmes

Maintenant, il faut mettre les mains dans le cambouis. Je vais modifier le thème WordPress de mon blog pour afficher mes thèmes dans la partie latérale de mon blog. Par défaut, WordPress gère la navigation par catégories dans un fichier nommé sidebar.php. J’y ajoute le code suivant :

<ul>
<?php
wp_list_categories('title_li=&orderby=name&show_count=0&use_desc_for_title=1&child_of=3');
?>
</ul>

wp_list_categories est une fonction standard de WordPress pour afficher la liste des catégories. Grâce à ses options, je vais pouvoir placer la racine de mon arbre sémantique :

  • title_li=
    Indique que je ne souhaite pas afficher de titre avant la liste.
  • orderby=name
    Ordonne les catégories par nom.
  • use_desc_for_title=1
    Affiche les catégories sous leur catégorie mère.
  • child_of=3
    Limite la liste aux catégories appartenant à la catégorie 3 (donc Thèmes).

Etape 4 : créer les mots-clés

Les mots-clés sont créés sur le même principe. Je les saisie donc dans le gestionnaire de catégories de WordPress, sous la catégorie Mots-clés.

Mots-clés sous WordPress
La liste de mes mots-clés dans l’interface de WordPress.

Etape 5 : afficher les mots-clés… dans un joli tag cloud

Pour afficher les mots-clés, j’aurais pu me simplifier la vie en reprenant le même principe que pour les thèmes. Dans ce cas, le code suivant suffit :

<ul>
<?php
wp_list_categories('title_li=&orderby=name&show_count=0&hierarchical=0&child_of=4');
?>
</ul>

Mais présenter les mots-clés sous forme d’un tag cloud est quand-même plus « tendance ». Un tag cloud met en valeur les mots-clés (tags) les plus utilisés. Pour cela, inutile de réinventer la roue, j’utilise une extension WordPress très simple et efficace : Category Tagging.

Une fois installée et activée, je n’ai plus qu’à générer le tag cloud dans l’interface :

<ul>
<?php
// Affichage du tag cloud (via plugin Category Tagging)
if (function_exists ('cattag_tagcloud') ) {
echo cattag_tagcloud(1,5,1,'NAME_ASC','1,2,3,4,5,6,7,8,9','','<li><a rel="tag" href="%link%" title="%description%" class="tag-cloud-%size%">%title%</a></li>','Aucun mot-clé trouvé');
}
// Affichage simple
else {
wp_list_categories('title_li=&orderby=name&show_count=0&hierarchical=0&child_of=4');
} ?>
</ul>

A chacun de spécifier ses paramètres (voir le détail sur le site de Category Tagging). Le plus important est sans doute le 5e paramètre qui exclut des catégories. Je l’utilise ici pour ne pas afficher les catégories racines (Thèmes et Mots-clés), ainsi que les thèmes de premier niveau qui sont déjà dans l’interface.

Reste à définir les styles CSS pour afficher les mots-clés en fonction de leur utilisation. Pour moi, c’est le code suivant :

a.tag-cloud-1 {
	font-size:1em;
	color:#9B907F;
}
a.tag-cloud-2 {
	font-size:1.2em;
	color:#7C6E59;
}
a.tag-cloud-3 {
	font-size:1.4em;
	color:#7C6E59;
}
a.tag-cloud-4 {
	font-size:1.6em;
	color:#666;
}
a.tag-cloud-5 {
	font-size:1.8em;
	color:#444;
}

Inconvénients

Comme toute astuce, la solution n’est pas idéale. Il y a aussi des inconvénients :

  • L’ajout d’un tag n’est pas possible pendant la saisie d’un article. En effet, WordPress propose l’ajout de catégorie pendant la rédaction, mais il semble impossible d’ajouter une sous-catégorie. Si quelqu’un connait le truc, je suis preneur !
  • Il faut modifier le code du thème WordPress pour gérer la liste des catégories à ne pas afficher dans le tag cloud. C’est le cas quand j’ajoute ou supprime un thème principal… ce qui est très rare.

Avantages

La solution n’est peut-être pas idéale, mais c’est un bon compromis :

  • On se passe d’un gestionnaire de tags. WordPress s’en trouve plus léger et plus stable.
  • Au niveau des articles, je peux afficher les thèmes et les mots-clés dans la même liste pour proposer un choix plus large aux lecteurs.
  • Si un mot-clé prend de l’importance, je peux le placer dans les thèmes sans toucher aux articles, ni aux outils de navigation. Pour faire la même chose avec un système de tags indépendant, il faut modifier chaque article…

Mise à jour. Thomas VdB voit deux autres avantages essentiels à utiliser les catégories comme arbre sémantique :

  • Les doublons disparaissent (comme Sémantique, sémantique et semantique qui sont habituellement considérés comme trois tags différents).
  • Le référencement est optimisé car l’adresse d’une page d’un tag décrit son contenu et facilite son indexation (par exemple, /category/mots-cles/web-semantique/).

Launchpad, un bon exemple de service collaboratif

Launchpad

Canonical, éditeur des solutions Ubuntu, nous propose Launchpad (version 1.0 beta), un service dédié aux développeurs open source, similaire à SourceForge.

Après une visite rapide, cet outil me laisse une impression très positive. Tout a été pensé pour faciliter le travail quotidien des développeurs et les fonctionnalités sont riches (code repositories, gestion de versions via CVS et Subversion, bugs tracker, support, gestion des traductions, etc.).

Hormis les produits développés par Canonical, Launchpad héberge quelques projets essentiels, comme Zope ou Creative Commons. J’y mettrai peut-être aussi les projets que j’ai dans mes cartons…

Il n’y a qu’un truc que je n’ai pas trouvé : la liste des projets hébergés. Cette fonction m’est très utile dans SourceForge pour suivre l’actualité des projets open source et trouver des perles rares.
Mise à jour : si, si, on peut avoir la liste de tous les projets. Merci Christian pour ton oeil de lynx !

Javascript et ActionScript : le piège de parseInt()

Comme tous développeurs pressés, nous utilisons très souvent des fonctions de façon empirique, sans en comprendre le fonctionnement réel et les subtilités de paramétrage. Et parfois, on le paye cher en mal de crâne, suite à des comportements incompréhensibles… et pourtant normaux.

Prenons la fonction Javascript parseInt(). Elle permet de transformer une chaîne en nombre entier. Si on veut récupérer le département d’un code postal, le premier réflexe est de faire :

var departement = parseInt(codepostal.substring(0, 2));

En apparence tout fonctionne bien… sauf pour les départements 08 et 09 pour lesquels on obtient 0 ! Diable…

C’est oublier un peu vite le second paramètre radix qui définit la base numérique à utiliser. Il est vital car en son absence, la base numérique dépend du format de la chaîne. Dans notre cas, les codes postaux commençant par 0 sont convertis en entiers de base octale (ou base 8). Notre but est d’obtenir un entier en base décimale (ou base 10), on précise donc la valeur 10 au second paramètre de la fonction parseInt() :

var departement = parseInt(codepostal.substring(0, 2), 10);

Ouf ! Pour information, radix supporte les valeurs 0 (valeur par défaut, sélection d’une base hexadécimale, octale ou décimale selon le format de la chaîne) et de 2 à 36. Par exemple, si on souhaite un entier hexadécimal, radix sera égal à 16.

On ne m’y reprendra plus !

Behaviour, ou comment piloter Javascript par les sélecteurs CSS

En attendant que s’impose un langage web qui réconcilie les développeurs, les marketeurs et les visiteurs (à mon avis, on en est très loin…), on est bien obligé de faire avec le HTML. Donc d’accepter un joyeux mélange dans le code d’une page web : contenu textuel et visuel, méta-données, informations de mise en page et de styles, appels à des comportements interactifs, paramètres d’objets externes, etc. Même avec la meilleure volonté du monde (par exemple, un site « 100% XHTML, 100% accessible, 100% CSS2 »), il est impossible de séparer totalement le contenu, sa présentation et son comportement.

Après avoir critiqué cette situation absurde, Ben Dolan nous propose une solution simple et astucieuse pour la partie interaction, grâce à son script Behaviour. Son objectif : éliminer tous les appels aux comportements Javascript dans le code HTML et les déclencher grâce au DOM et aux sélecteurs CSS.

Une idée toute bête, encore fallait-il y penser. Du coup, toutes les interactions peuvent être modifiées sans toucher au code HTML. Du pur bonheur !

ACID (Atomicity, Consistency, Isolation, Durability)

Alors que je suis en pleine période des acronymes de quatre lettres (CRUD et UDOD), je découvre ce matin un bon résumé d’ACID sur Le Journal du Net.

J’ajouterais à l’article de Xavier Borderie que ces quatre attributs d’une transaction de données (Atomicity, Consistency, Isolation, Durability) ne se limitent pas aux bases de données. Ils sont utiles dans bien d’autres contextes, comme par exemple la gestion d’un annaire LDAP ou les transactions entre un repository Subversion et ses utilisateurs. Sauf à considérer qu’il s’agit là de bases de données au sens large et théorique…

Par contre, il y a un contexte où ACID mériterait d’être strictement appliqué, c’est celui des transactions entre un serveur et un navigateur web ! Nous en sommes très loin car le socle technique n’a pas été prévu pour cela. Par exemple, on ne peut toujours pas savoir quand un utilisateur quitte un site ou une application web, ce qui est gênant quand l’application web fait des opérations par étapes successives avec confirmation de l’utilisateur pour chacune d’elles. Doit-on annuler les étapes précédentes ? Si oui, sous quel délai ? De plus, laisser une session ouverte sur le serveur représente un risque de sécurité.

On peut simuler la persistance des sessions et des objets par les cookies, mais la fiabilité n’est pas au rendez-vous (sauf en dérivant le navigateur par des extensions particulières, comme des applets Java). On peut faire un semblant d’atomicité en plaçant les pages web dans un buffer avant de les servir (pour éviter une validation d’un formulaire incomplet par exemple). On peut assurer la cohérence en contrôlant rigoureusement les requêtes HTTP. On peut gérer l’isolation par l’utilisation de « sémaphores maison ». Quant à la durabilité, je ne vois pas comment l’obtenir…

Il manque donc un maillon pour simplifier le développement et gérer la robustesse des applications web : si ACID est bien présent entre le serveur web (front office) et les entrepôts de données (SGBD, annuaires, systèmes de fichiers, échanges de données…), son absence entre le navigateur et le serveur web rend le développement et l’exploitation difficiles.

UDOD, User documentation oriented design

Allez, je me lance ! Ce soir, j’invente un nouveau concept : le UDOD (User documentation oriented design).

Après tout, chaque jour, les acteurs du web inventent de nouveaux « concepts », toujours révolutionnaires, avec leurs centaines de termes et abréviations à connaître par coeur pour rester « in » ! On recherche, on découvre, on apprend, on applique, on oublie et on recommence. C’est tout le charme d’internet ! En regardant de près (ou plutôt de loin si on veut prendre du recul), il y a peu de concepts réellement nouveaux, mais ça fait monter le « buzz » ! Le « web 2.0 » en est une caricature…

« Et UDOD, ça apporte quoi de neuf ? »

Evidemment, après avoir dit tout ce que je pense des « révolutionnaires du web », je vais avoir un peu de mal à vous convaincre d’utiliser UDOD… Mais comme je l’applique avec de bons résultats, je me dis qu’il y aura bien quelques intéressés !

Le principe de UDOD est simple : après avoir fait un brief rapide et fixer des objectifs assez larges pour votre nouvelle application (méthodologie Paper prototyping), vous commencez par écrire la documentation de l’utilisateur débutant (« User guide for beginners »). L’intérêt est de poser une fois pour toute une description claire, synthétique et compréhensible de votre application. On devrait donc y trouver au moins :

  • une définition de l’application ;
  • une présentation des notions fondamentales ;
  • une description des fonctions principales et de leur utilisation ;
  • une description de l’architecture et de son interaction avec d’autres sytèmes ;
  • des annexes pour les détails techniques ;
  • un glossaire ;
  • un index.

Une architecture claire, des notions définies

Certes, cela a un coût. La rédaction est longue et doit être faite par un spécialiste. Cependant, on découvre vite l’intérêt de cette méthode :

  • La définion de l’application facilite la compréhension des objectifs pour l’équipe de développement.
  • Les notions fondamentales sont exhaustives et définies.
  • La description des fonctions donnent l’étendue du travail (orienté tâches) de développement et de conception de l’interface.
  • La description de l’architecture pose les bases du noyau de l’application.
  • Les annexes précisent les contraintes pour les développeurs.
  • Le glossaire définit tous les éléments de l’application.
  • L’index permet de valider la cohérence des termes utilisés.

Entendons-nous bien, je n’ai pas dit qu’il fallait finir la documentation avant de faire autre chose, mais bien de commencer par elle. Les autres méthodes de conception viendront compléter UDOD sans accroc :

  • Design participatif ;
  • Méthodes agiles ;
  • User task oriented design pour la conception de l’interfaces ;
  • UML pour la modélisation de l’application ;
  • Object oriented programming et Aspect oriented programming pour le développement du code ;
  • Unit tests pour valider chaque brique fonctionnelle définie par UDOD ;
  • et j’en passe…

Des utilisateurs impliqués

L’équipe interne a maintenant de quoi travailler sereinement. Mais il y a mieux encore : UDOD implique très vite les futurs utilisateurs de votre application. Ils peuvent la découvrir avant même qu’elle ne soit codée. Et bien sûr y apporter rapidement des remarques, des contraintes, de nouveaux besoins. Dans le cadre d’une application métier, la qualité des échanges est nettement améliorée. On applique au mieux les méthodes de design participatif !

Une documentation de qualité

Au bout du compte, vous aurez optimisé tous les cycles de développement. Et je garde le meilleur pour la fin : vous avez une documentation utilisateur claire et complète au lancement de l’application ! C’est tellement rare…

N’oubliez pas CRUD !

Cela peut sembler étonnant, mais je constate assez fréquemment l’absence ou la mauvaise implémentation de fonctions basiques et indispensables dans les applications web. Souvent, cette situation vient d’une conception architecturale bâclée (voire absente…) et de l’utilisation extrême et non contrôlée des méthodes agiles (« Ajoute cette fonction maintenant, le client vient de me la demander pour la démo de 14h ! »).

La détection de ces défections peut se faire à différentes étapes du projet :

  • pendant la conception de l’architecture ;
  • pendant l’écriture du code ;
  • pendant la phase de test des briques fonctionnelles ;
  • pendant la phase de finalisation de l’application (version alpha ou beta) ;
  • pendant l’utilisation du produit en production.

Autant dire qu’une détection précoce sera la bienvenue…

Parmi les oublis classiques, celui de la gestion des données est le plus fréquent. « Ah ben ça alors… Je peux créer un utilisateur, mais pas le supprimer ! » Quand c’est votre client qui le dit, votre réputation en prend un coup ! Pour éviter ce genre de surprise, n’oubliez pas CRUD (Create, Read, Update, Delete) ! Et posez-vous les bonnes questions :

  • Create
    Dans quelles circonstances créer la donnée ? Qui peut le faire ? Comment avertir l’utilisateur quand elle est créée automatiquement ? Comment le faire manuellement dans l’interface ? Comment gérer les erreurs de saisie ?
  • Read
    Comment récupérer la valeur ? Qui peut la lire ? Doit-on la transformer pour l’afficher ? Comment vérifier que la donnée retournée est bien la bonne ? Que faire si elle n’existe pas ?
  • Update
    Qui peut le faire ? Comment avertir l’utilisateur quand elle est créée automatiquement ? Comment le faire manuellement dans l’interface ? Comment gérer les erreurs de saisie ? Quelles sont les répercussions sur les autres données ? Comment vérifier le type et le format de la donnée modifiée ? Que faire si elle n’existe pas ?
  • Delete
    Dans quelles circonstances supprimer la donnée ? Qui peut le faire ? Que se passe-t-il quand je supprime la donnée ? Faut-il ajouter, modifier ou supprimer d’autres données ? Que faire si elle n’existe pas ?

Ces questions (et bien d’autres !) doivent bien sûr être posées et résolues pendant la phase de conception de l’architecture car elles définissent le socle fonctionnelle de l’application, sa stabilité, sa robustesse et son évolutivité.

CRUD, CRUD, CRUD…