Blog

Accueil   Contacts
Accueil

lundi 29 mai 2006

Matisse, un designer visuel intelligent

L'interface graphique d'une application d'entreprise est par nature très volatile. Elle évolue continuellement pendant tout le cycle de vie de l'application. Et c'est bien naturel : l'interface graphique constitue la partie visible de l'iceberg applicatif. Son ergonomie impacte directement la productivité des utilisateurs, et leur adhésion à l’application.

Autre problématique, l’interface graphique ne peut maintenant plus reposer sur un positionnement absolu des composants graphiques dans les formulaires. En effet, de nombreux paramètres changent d’un poste utilisateur à un autre : résolution de l’écran, taille des polices, langue utilisée. Pour gérer ces aspects, les layout managers sont petit à petit en train de devenir la norme, aussi bien en .NET qu’avec Java. Précurseur dans ce domaine, le monde Java connaît trop bien les difficultés de ce type d’approche pas forcément toujours très naturelles pour le commun des mortels. Après quelques errances, l’expérience a permit de faire émerger des layout managers à la fois suffisamment puissants et raisonnablement complexes.

Pour pouvoir faire face aux changements continuels et inévitables, il faut des outils à la fois réellement productifs à la première mouture de l’interface, mais également lors des (très) nombreuses modifications ultérieures. Ces outils doivent permettre d’élaborer simplement des interfaces graphiques à base de layout managers.

Mais, il faut bien l’admettre : les outils de conception d’interface graphiques issus des outils RAD d’antant ont plutôt mal vieilli, en regard des nouvelles exigences des projets. Peu efficaces et peu agiles, ils favorisent une approche par codage direct, souvent beaucoup plus efficace, mais pas très accessible, et pas forcément très compatible avec un travail en équipe. Les créateurs de Matisse n’ont visiblement pas souhaité se résigner, et ont plutôt choisi d’innover.

Matisse, c’est l’éditeur de formulaire de NetBeans 5.0, un IDE open source connu dans le monde Java. Avec une interface d'une simplicité biblique, Matisse ne paye pas de mine : quelques icones dans la barre d'outils, quelques lignes dans le menu contextuel. En apparence frustre, Matisse recèle des trésors d'intelligence. D’abord, il réduit drastiquement le nombre de manipulations à effectuer pour créer une interface graphique. Il permet également d’effectuer très rapidement de nombreuses modifications classiques. Sans que le développeur ait à s’en soucier, Matisse respecte les conventions standards de la plateforme : écartement entre deux composants, écartement entre un composant et le bord de la fenêtre, indentation d’un composant par rapport à l’autre … Les interfaces crées reposent sur un layout manager. Ainsi, les composants se retaillent automatiquement en fonction de la taille de la fenêtre. Matisse élimine presque complètement le surcoût liés aux layout managers, et permet une productivité largement supérieure.

Bien entendu, tout n’est pas parfait, mais on sent clairement qu’une nouvelle voie est ouverte pour des outils réellement intelligents. Ainsi, avec Matisse, on a réellement la sensation d’être accompagné par un expert de l’interface graphique.

Liens

vendredi 19 mai 2006

Du code-blob et de la qualité du code

Dans la mythologie de l'heroic fantasy, le blob est un monstre gélatineux, de grande taille, dans lequel on ne parvient à distinguer aucune structure particulière. Tel un globule blanc, cette créature phagocyte tout ce qui s'en approche, et grossie à mesure qu'elle se nourrit. Le blob inspire la crainte, et personne ne souhaite vraiment s'en approcher.

Le code-blob, c'est une portion de code de l'application (généralement le corps d'une méthode ou d'une fonction) constituée d'un nombre important de lignes. Les blocs conditionnels et les boucle sont de grande, voire de très grande taille. Le niveau d'imbrication est élevé. L'ensemble n'est pas structuré, et aborde d'un seul tenant de très nombreuses considérations : écriture dans un fichier texte, accès à une base de données, parsing d'un fichier XML, traitement métier, délimitation du périmètre transactionnel, libération des ressources, gestion d'erreur ...

L'ensemble est très peu compréhensible. Certes, avec du temps et de l'énergie, on n'arrive effectivement à en acquérir une compréhension grossière. Le code 'blob' reste cependant très difficile à faire évoluer, à déboguer et à tester unitairement. En cas de problèmes de performances, le diagnostic est également considérablement complexifié.

Bien-sûr, personne ne souhaite vraiment intervenir dans un tel code. Ceux qui s'y frotte ajoutent généralement quelque lignes à la marge, et accumule les astuces pour ne pas risquer de perturber le fonctionnement de ce fragile édifice. Ce faisant, on nourrit le blob et il devient plus gros encore. Mais alors, pourquoi ne pas tuer le blob, plutôt que de le nourrir ?

Le problème est qu'en tuant le blob d'un coup net, il faut trouver une solution de rechange. Il faut soit réécrire, soit se lancer dans un refactoring plutôt ambitieux. Le coût d'une telle opération est difficile à justifier, d'autant plus qu'elle aboutit à des fonctionnalités strictement identiques. Cette approche contribue également à présenter la qualité uniquement sous la forme d'un coût, avec des bénéfices apparemment faibles.

Clairement, il est préférable de tuer le blob à petit feu : organiser progressivement l'intérieur du bloc, sortir progressivement les parties saines et les péreniser. Un tel travail n'est pas une tâche spécifique dans un planning, c'est un effort continu disséminé tout au long du projet. Au même titre que les tests unitaires, le maintien de la qualité du code est un effort réalisé lors de chaque tâche de développement.

Certes, on peut se trouver toutes les bonnes raisons du monde de remettre ce travail au lendemain. Mais il faut bien se dire qu'un code-blob nait de l'accumulation de petits efforts jamais entrepris. Annihiler un blob naissant ne prend que quelques minutes, tout au plus une demi-heure. Pas de quoi justifier un tâche dans un planning.

vendredi 12 mai 2006

SOA, les services … et les processus

La SOA, comme son nom l’indique est une architecture fondée sur les services. Mais, à tant parler de services, n’aurait-on pas perdu de vue les processus.

En première approche, on peut définir un processus comme un enchainement de tâches. Un processus peut être coordonné par un acteur unique, on parle alors d’orchestration, ou par coopération entre des acteurs coordonnant chacun une sous partie du processus, on parle alors de chorégraphie. Au sein d’un système d’information, la plupart des processus sont exécutés par orchestration. Et c’est seulement lorsqu’un processus implique plusieurs systèmes d’information (entre partenaires par exemple) que le mode d’exécution par chorégraphie est généralement intéressant.

Les processus les plus simples correspondent à des traitements exécutés de bout en bout, sans interruption. Un tel processus est sans-état, et invoque le plus souvent des services lors de son exécution. Un processus procédural peuvent être implémentés via des langages spécifiques (DSL ou Domain Specific Language) ou bien directement dans un langage classique tel que C# ou Java.

D’autres processus sont avec-état et sont pilotés par des événements. Un tel processus prend naissance suite à un événement métier spécifique (état initial). Le processus suit ensuite son cours en fonction de l’occurrence d’autres événements métiers (états intermédiaires), et s’achève à un moment donné (état final). Un processus événementiel a pour particularité de pouvoir se mettre en sommeil, pendant un temps indéterminé, dans l’attente de tel ou tel événement métier. Un tel processus a bien un début et une fin, mais contrairement au processus procédural, il peut se mettre en attente. Dans ce cas, l’état d’avancement du processus doit être sauvegardé, pour permettre au processus de reprendre plus tard. Les langages classiques ne sont pas adaptés à la description de tels processus. Seul des langages spécifiques comportant la notion d’état d’attente sont adaptés.

La notion de processus permet de décrire des business process, des traitements divers, et pourquoi pas la navigation dans un site Web. Les processus peuvent invoquer des services lors de leur exécution. Cette approche permet de donner une vision globale sur le processus, les détails sont ensuite implémentés par les services. Le processus modélise ce qui est variable dans le temps, alors que les services implémentent ce qui est stable dans le temps.

Finalement, la SOA n’a-t-elle pas pour enjeux de déterminer ce qui est de l’ordre du service et ce qui est de l’ordre du processus ?