BodySplash.fr

Aller au contenu | Aller au menu | Aller à la recherche

vendredi 17 septembre 2010

Frameworks productifs

J'aimerai ici faire un billet pour faire une petite mise au point. Les frameworks "productifs" type RoR, Grails, Play! et j'en passe ont clairement le vent en poupe. L'idée au combien louable, est bien sûr d'automatiser au maximum les tâches rébarbatives du développeur lorsqu'il s'attaque à une application web. J'imagine que toute cette mouvance a pu naître d'un écoeurement bien naturel vis à vis des piles ou frameworks plus anciens, comme Struts, toute la pile JEE et même ASP.NET avec ses bons vieux WebForm.

Ce qui me chagrine dans l'histoire, c'est que philosophiquement, je suis de tout coeur derrière ces idées de simplifications : je n'ai jamais pu encadrer le xml au kilomètre de Spring à l'époque, les Web Form me faisaient faire des cauchemars tant leur opacité était grande et je n'ai jamais été pour une multiplication des couches sans une grande nécessité.

Ceci dit, ne jetons pas le bébé avec l'eau du bain. Je m'explique. Pour paraphraser Eric Evans dans DDD, la complexité d'une application réside dans le métier qu'elle tente de représenter. Comment cela se traduit? Pour moi, cela veut dire que quelque soit les frameworks que j'utilise, ils ne devront jamais entamer ma capacité à modéliser le métier. Le succès, la richesse et l'efficacité de mon application dépendent essentiellement de ma capacité à capter la subtilité du métier. Comment mettre le maximum de chance de mon côté? En développant le modèle en isolation de tout autre considération, à l'aide d'une approche objet, d'un bon framework de tests unitaires et de bons outils de refactoring. La présentation, la persistence, le cache, tout le reste est superflu et doit le moins possible, voir pas du tout, impacter mon domaine.

Bref, après autant de blabla, voilà donc enfin ce qui me chagrine dans ce que j'ai pu voir des quelques frameworks productifs que j'ai essayé : ils sont invasifs. Le choix d'Active Record pour la persistance est une friction dans le développement du métier, car la persistance n'est alors plus transparente. Pour respecter le principe de responsabilité unique, vu que les "entités" gèrent la persistance, nous devons développer les véritables objets métier à part, et ils doivent agréger alors ces entités. Cela implique une complexification non négligeable du développement du domaine. Du coup, beaucoup des exemples que j'ai pu observer se contentent de montrer une application CRUD, avec un métier anémique contenu dans les contrôleurs, mais aucune application n'est réellement du CRUD au final.

La véritable productivité est liée à la maintenabilité, et la maintenabilité est très liée à l'isolation du métier (et aux tests bien sûr :) ). Oui du coup, avec cette philosophie en tête sur Tiron, nous n'avons pas choisi un de ces beaux frameworks à la mode, et nous avons du construire notre propre pile (jQuery/Restlet/Freemarker/Hibernate pour les curieux), et je pense que notre productivité actuelle en considérant la complexité du métier que nous devons gérer n'a pas à pâlir face à la concurrence.

P.S : je ne suis pas un expert de ces frameworks je l'avoue. Si quelqu'un peut me démontrer le contraire de ce que j'avance, j'en serai très heureux.

mercredi 9 juin 2010

Le secret de la productivité

Je vais peut être enfoncer une porte ouverte pour certains, mais j'ai envi de parler du secret si bien gardé par les grands professionnels pour être productif avec un IDE : les raccourcis clavier! Oui, c'est ironique, mais l'année dernière lors de la session TDD, et plus récemment suite à d'autres retours, j'ai été assez étonné des remarques du genre "ah je ne savais pas qu'on pouvait faire tout ça avec Eclipse". Un des intérêts premiers d'un IDE est tout de même de nous aider à faire les tâches de base du développement :

  • autocomplétion
  • refactoring
  • exécution des tests
  • navigation facile dans les sources
  • assistance contextuelle

Oui, je ne met pas sciemment tout ce qui est éditeurs WYSISYG, car leur utilité est finalement assez anecdotique et bien souvent alourdissent les IDE pour rien tout en étant pas si productif que ça. Ils sont d'ailleurs peut être la cause majeure qui fait que pas mal de gens n'aiment pas les IDE. Ceci dit étant dit, même si la plupart des fonctionnalités citées plus haut sont accessibles par la souris, leur usage ne devient systématique et efficace à mon avis que si on les associe à des raccourcis claviers.

Prenons un petit cas d'exemple. Imaginons que j'ai écrit un test ressemblant à ça (désolé, je ne me suis toujours pas motivé pour mettre en place une coloration syntaxique sur ce blog):

@test
public void peutRécupérerNomComplet() {
    Client client = new Client();

    assertThat(client.nomComplet(), is("prenom nom");
}

au plus simple, le code pour faire passer ce test est le suivant :


public String nomComplet() {
   return "prenom nom";
}

Cette méthode est un appel au refactoring, car il y a duplication entre la méthode de test et la méthode de production (la constante est répétée). Je vais peut être vite en besogne, mais nous devons alors faire apparaître du coup le nom et le prénom. Pour éviter d'être verbeux plus longtemps, voici une petite vidéo pour montrer comment je m'y prend en m'appuyant sur les capacités d'Eclipse:

(Si jamais la vidéo ne s'affiche pas, vous pouvez toujours allez directement ici)

Il y a bien sûr plusieurs chemins pour arriver au même résultat, mais j'espère que si vous n'utilisez pas souvent les raccourcis clavier, les refactorings ou les aides à la génération alors cette vidéo vous aura convaincu d'essayer de vous y mettre un peu plus. Beaucoup de développeurs reprochent aussi aux IDE leur lourdeur. C'est parfois justifié (je ne citerai personne), mais dans cette vidéo, avez-vous vous eu l'impression qu'Eclipse était lent et se mettait sur mon chemin?

samedi 6 mars 2010

Redécouvrir JavaScript

Comme beaucoup de monde, j'avais une certaine aversion pour JavaScript. Ces derniers mois m'ont permis de remettre un peu en perspective pas mal de mes anciennes croyances. Vous allez sans doute me demandez comment la magie à-t-elle opérer (ou pas)? Et bien en fait assez simplement à partir du moment qu'on décide de lui donner sa chance, et d'arrêter de se contenter de hacker quelques bouts copiés/collés à droite à gauche. Voici en tout cas pour moi les grands points qui m'ont permis non pas de devenir un expert, mais de pouvoir m'en servir sans hurler à la mort :

  • Le plus gros manque finalement au départ de javascript, c'est un framework de base livré avec l'engin. Sans ça, on a l'impression de réinventer 100 fois la roue, et de perdre pas mal de temps à faire la même chose. Le premier conseil est donc d'utiliser une des fantastiques librairies qui vivent dans le coin. Leur philosophie peut varier, donc méfiance, mais je préfère personnellement m'appuyer sur jQuery, car je le qualifierai bien de plus simple qui fonctionne. Il est malgré tout à la fois très puissant et extensible à souhait. Je dois avouer que du coup je n'ai pas trop essayé la concurrence qui en comparaison semblait bien plus complexe.
  • Il faut se rendre compte que JavaScript est un vrai langage, avec son propre paradigme, et qu'il ne sert donc à rien de tenter de ramener toutes ses habitudes de nos langages favoris (java, c#, python ruby, choisissez celui qui vous fait plaisir). Comprendre ce qui se passe et les quelques concepts de base qui animent le langage fait déjà beaucoup pour commencer à l'apprécier. C'est pour cette raison par exemple que encore une fois je préfére jQuery à prototype, car il n'essaye pas d'ajouter un support "classique" de l'orienté objet au langage, il lui demande juste d'être lui même, naturellement. J'aimerais bien vous conseiller un bon tutorial sur le sujet, mais hélas j'ai appris tout ça dans deux bouquins.
  • Le conseil bateau maintenant, il faut s'abstraire le plus possible du navigateur en utilisant une bonne librairie : ça recoupe en grande partie le premier point, mais c'est surement le soucis qui retient beaucoup de monde à apprendre Javascript. jQuery fait un boulot fantastique pour faire oublier là plupart des soucis de compatibilité, même s'il reste bien entendu quelques problèmes à droite à gauche.
  • Enfin, mais sans doute le point plus important, les bonnes pratiques de programmation ne sont pas à jeter tout simplement car on se trouve côté navigateur. Il n'y a pas de secret, le seul moyen de vraiment tirer partie de javascript est d'appliquer les bonnes pratiques, DRY et TDD en tête de liste. Il existe quelques frameworks de tests unitaires en javascript, même si rien n'est parfait bien entendu pour le moment dans ce domaine, surtout lorsqu'il s'agit de les faire tourner automatiquement pendant l'intégration. TDD fonctionne bien en javascript encore une fois du moment qu'on essaye de pas de tordre le langage dans un orienté objet "classique". Pour reparler, encore, de jQuery, développer ses fonctionnalités sous la forme de plugin pour ce dernier les rend incroyablement plus testable et réutilisable.

Ma conclusion finalement serait qu'il y a encore quelques mois, je lorgnais beaucoup du côté GWT pour les mauvaises raisons : la peur de javascript. Paradoxalement, avoir adopté ces derniers mois Restlet, freemarker et jQuery a beaucoup simplifié le développement que les quelques essais avortés avec GWT. Le plaisir des choses simples il faut croire :) Ces framework sont solubles dans une approche ROA là ou GWT l'est beaucoup moins.

Pour aller plus loin, javascript commence même à envahir la programmation côté serveur grâce aux deux initiatives CommonJs et Node.js. Il y a un bon article sur le sujet dans le pragpub de ce mois-ci

lundi 18 janvier 2010

.NET vs JEE

Voilà un titre de billet accrocheur! En fait, je vais me contenter de réagir à cet article d'Ayende Si vous écoutez un peu les voix alternatives du monde .NET, vous devez surement avoir déjà entendu parler de lui, sinon sachez juste qu'il est contributeur sur NHibernate, qu'il a initié l'implémentation de Linq2NHibernate, et qu'il a fait pas mal d'autres projets open source dans le monde de .Net, ainsi qu'un profiler propriétaire mais excellent pour NHibernate et Hibernate. Bref, ce bonhomme est très bon techniquement, et je suis toujours avec attention ses avis (notamment sur la mutualisation, désolé pour la private joke, mais les initiés comprendront :) ).

Bref, dans l'article que je donnais en début de billet, il donne donc son avis sur JEE vs .NET. Je suis globalement très d'accord avec lui sur son jugement sur JEE, et sur certains manques du langage Java. Cela fait maintenant un peu plus d'un an que je fais du Java 100% du temps, et que je ne touche plus à .NET, et pourtant je passe encore pas mal de temps à regretter certains fonctionnalités de C#. Ceci dit, cela fait également plus d'un an que je m'efforce le plus possible à ne PAS utiliser JEE. Et je pense que c'est un peu ça la force de Java vs .NET : une communauté réactive qui passe le plus clair de son temps à essayer de ne pas appliquer la philosophie "main stream" et à développer des alternatives . Mieux encore, il est tout à fait possible en entreprise d'utiliser ces projets open source sans rencontrer trop de résistances. Lorsque que je bossais en .NET, convaincre un client d'utiliser NHibernate (à une époque ou Entity Framework n'existait pas) relevait du défis, à tel point que j'ai été contraint dans une mission d'écrire mon propre mapper O/R. A ça ajouter une communauté, si on peut l'appeler ainsi, provenant majoritairement d'un monde VB6 sans bonnes pratiques, et vous obtenez une mini catastrophe. Des mouvements comme Alt.NET sont bien sûr à saluer et regroupent de très bon praticiens, mais je pense qu'ils représentent toujours hélas une minorité dans l'ensemble des développeurs .NET. Biens sûr tout n'est pas rose côté communauté Java, et elle comprend son lot de boulets et de mauvaises idées. Mais le simple fait qu'il soit tout simplement possible d'avoir le choix rend cette technologie plus attractive maintenant à mes yeux. Nous utilisons principalement Restlet dans Le Projet, et à ma connaissance, il ne connait pas d'équivalent en .NET aussi simple d'utilisation et de configuration. Le monde Java est un monde où les idées peuvent plus facilement s'épanouir j'ai l'impression, et où le réflexe "alternative open source" est bien plus ancré.

mardi 8 décembre 2009

AppEngine

Aujourd'hui, je vais essayer de parler un peu d'AppEngine.

Rapidement

Commençons par un peu de présentation. Pour ceux du fond qui ne le savent pas, AppEngine, c'est le système d'hébergement mutualisé made in google pour des applications développées soit en Python, soit en Java. L'idée est donc de développer tranquillement son application, et de laisser à google la responsabilité de l'infrastructure et de la montée en charge. Niveau facturation, on ne paie que ce qu'on consomme à partir d'un certain quota.

Déjà, le premier point que j'aimerais souligner, c'est que nous disposons enfin d'une offre solide et abordable d'hébergement mutualisé pour Java (pour python, on pouvait déjà trouver son bonheur en fouillant un peu). Ça n'a l'air de rien comme ça, mais j'ai envie de dire c'est pas trop tôt. Voilà près de 10 ans qu'il est très facile de trouver un hébergement mutualisé pour Php, mais qu'il est très difficile voir impossible de trouver une offre équivalente pour d'autres technologies. Du coup, PHP est presque devenu un standard sur le net, alors qu'il est sans doute difficile de trouver pire environnement de dev (support des TU lacunaire, pas de refactoring, un style très procédural, une communauté globalement très mal formée et sensibilisée aux bonnes pratiques de développement, pas de framework unifié de base, etc. etc.). Alors bien sûr, je ne pense pas qu'AppEngine va réussir à inverser la tendance, mais j'espère juste qu'à l'avenir, des offres d'hébergement pour des technologies/langages plus "agréables" comme Python ou Ruby vont fleurir sur le net. Bref, après un paragraphe qui je suis sûr, va me faire lapider par tous les aficionados de php, passons aux choses sérieuses (vous pouvez m'envoyer vos cailloux par email).

Un peu (beaucoup) de technique

Parlons un peu technique. Je vais me contenter de parler de la partie java d'AppEngine, car je ne suis pas du tout un expert python, et je n'utilise que des langages pour lequel il existe un IDE avec un bon support du refactoring (et ceux qui disent que ces outils ne servent juste qu'à palier les manques d'un langage n'ont juste rien compris à ce qu'est fondamentalement le refactoring).

En terme de développement et de déploiement, si vous utilisez le plugin eclipse de google, tout est excessivement simple, et mérite à peine d'en parler : vous codez, vous testez, et vous déployez en un seul clique. Un serveur de développement AppEngine est fourni pour vous permettre de faire des tests d'intégration, et TDD peut s'utiliser sans aucune contrainte, en fakant rapidement l'accès aux données. IntelliJ IDea dans sa version complète je crois fournit également un support pour tout ça. Là où ça commence à être compliqué, c'est si vous voulez utiliser maven pour automatiser votre build et votre intégration. Clairement, ce n'est pas au point, et j'ai laissé tomber l'idée pour le moment.

Ceci étant dit, abordons les limitaions d'AppEngines. Pour garantir la scalabilité et la mutualisation de votre application, Google a dû imposer des contraintes de taille.

Première contrainte, toutes les fonctionnalités de l'API java ne sont pas à votre disposition. Les deux restrictions qui sautent aux yeux mais qui sont assez logiques sont l'impossibilité bien sûr d'écrire sur le FileSystem, ainsi que l'interdiction de créer des threads. Il y en a d'autres, mais je vous laisse la surprise, je ne veux pas trop spoiler.

Deuxième contrainte très importante, et c'est celle qui va le plus nous intéresser : le stockage de vos données. Et oui, vous ne pouvez pas utiliser votre cher SGBD. C'est assez logique en fait. Pour garantir la scalabilité et la vitesse d'accès à vos données, google fournit son propre système, BigTable, pas du tout relationnel. Bon si cette base n'est pas relationnelle, qu'est-elle donc? Elle est hiérarchique. Ce genre d'approche permet de répartir bien mieux vos données sur N cluster, là ou les SGBD eux ont beaucoup plus de mal. Ce miracle est dû au fait que ces approches ne se concentrent par sur la cohérence des données, mai sur leur accessibilité et leur distribution, là où un sgbd se concentre sur l'accessibilité et la cohérence. Le bémol est donc que vous n'avez pas la garantie qu'à un instant T, une entité donnée est cohérente sur l'ensemble des noeuds. Ok, une base hiérarchique, c'est quoi donc? Vos données sont organisées en entités, contenant des propriétés clef/valeur de types supportés. Ces valeurs peuvent être d'autres entités. Le DataStore regroupe les entités par groupe, chaque groupe ayant une racine. Et là, normalement, si comme moi vous aimez Domain Driven Design, ça doit faire tilt dans votre tête. Entités? Groupe? Racine? Pouvons-nous réécrire ça en Agrégat, racine d'Agrégat et entité? Et bien oui, nous le pouvons. Nous avons face à nous un système de stockage mimant les grands concepts de DDD, et ça, c'est la classe. Nous pourrions normalement sauter de joie, mais hélas non, pas encore. Pour nous permettre de décrire la persistence, Google nous fournit une implémentation partielle de JDO ou JPA. Voilà déjà un premier point noir à mes yeux : pas d'ignorance de la persistance pour nos objets du domaine, vu que le mapping se fait donc nécessairement par annotations. Deuxième gros point noir, pour modélier une relation entre deux racines d'agrégats, nous devons nécessairement passer par la clef. Et oui, pas de mapping transparent entre deux racines : l'un ou l'autre contient la clef qui va nous permettre de faire la requête adaptée.

Dernière contrainte que je vais aborder : le développement itératif. Si vous suivez un modèle de développement agile correctement implémenté (ok disons que vous utilisez XP, ça ira plus vite), vous êtes incrémental et itératif. Itératif veut donc dire que votre modèle évolue au fur et à mesure des besoins et de votre compréhension. Si le modèle évolue, nécessairement sa persistance aussi. Le DataStore n'a pas du tout besoin que toutes les entités d'un même type possèdent les mêmes propriétés, donc on pourrait croire qu'en théorie pas de soucis. Oui mais si vous devez tout de même faire une mise à jour des vielles entités pour une raison X ou Y (notamment si vous avez ajouté un type valeur comme un boolean), comment faire? Voilà tout le soucis, actuellement, même si Google planche sur le sujet, vous ne pouvez pas facilement. Vous avez une limite de 1000 entités par requête, et une requête a un temps de vie très court accordé par le système avant d'être tuée. Il existe bien sûr des solutions de contournement, mais rien de bien simple et de pleinement satisfaisant.

Et pour conclure

Bien voici venu le temps d'une grosse conclusion. Ce que j'aime, voir ce que j'adore chez AppEngine, c'est enfin l'accès à un hébergement abordable et de qualité pour Java. Vous pouvez utilisez si vous développez avec AppEngine en tête dès le début vos frameworks et techos préférés (Groovy, Restlet, Spring, Guice <ajoutez ici votre techo>). J'adore également, et ce n'est pas seulement dû à AppEngine, l'attaque qui est faite aux SGBD traditionnelles. Des technologies solides de remplacement voient enfin le jour grâce à ces nouveaux services, et on peut espérer voir la fin de notre vivant des ces applications codées en procédures stockées, soit disant pour être performantes. Là vous n'avez pas le choix : votre métier est dans votre application, pas dans la base. Bien sûr, ce n'est pas encore complètement au point à mes yeux tant que l'ignorance de la persistance n'est pas atteinte, mais c'est sur une très bonne voie. Si vous ne voulez pas dépendre, à juste titre, de sociétés comme Google et Amazon pour stocker vos données, des implémentations solides et open source de ces nouvelles bases de données sont disponibles.

Enfin, je m'excuse si ma vulgarisation des théories derrière BigTable est vraiment lapidaire, mais je vous laisse bien entendu l'opportunité de me fustiger dans les commentaires :)

mercredi 24 juin 2009

Structure et frameworks

Voilà un titre bien obscure. Alors de quoi allons parler aujourd'hui? De la manière la plus simple que je vois actuellement de commencer une application web en java. Il y a quelques semaines effectivement un ami me demandait finalement quoi utiliser pour démarrer un projet de 0 e, avec comme postulat de base que finalement, tout était bien compliqué. Je vais donc décrire ici mes environnements/outils/frameworks favoris qui à mon sens, permettent de s'en sortir dans la grand majorité des cas, et tout en fournissant une base à la fois solide et extensible.

L'environnement

Avant même de commencer à développer, mieux vaut savoir comment nous allons développer. Je pense maintenant qu'il y a une base indispensable à tout projet avant même de penser conception et développement.

Build

Avec quoi construire notre appli? Ca a l'air bête comme question, mais ce n'est en fait pas si simple dans le monde de java, ou tout n'est pas aussi intégré et monolithique que dans le monde .NET.

Par défaut, à peu prêt tout le monde utilisait Ant. Personnellement, je n'en peux plus: xml au kilomètre, dépendances gérées à la main, pas user friendly, bref, une horreur à mes yeux. Si vous lisez de temps en temps ce blog, vous devez vous douter que je vais proposer Maven. Avec maven, il va être possible en 2 lignes de xml d'avoir un projet entièrement compilé, testé, packagé. Les dépendances sont téléchargées depuis un entrepôt central, et il les gère en cascade, donc on ne passe plus des heures à linker ou mettre à jour les libs externes, c'est géré. Si on suit ses conventions, c'est bien simple maven permet de faire oublier une grande partie des tâches techniques de base d'un projet.

Une question qui peut venir et savoir comment organiser son projet dans maven: Multi module ou mono module? l'avantage du multi module est qu'il va garantir une séparation entre les couches, là ou le mono module si on ne fait pas attention peut entraîner un certain mélange. Ceci dit, la complexité du multi module au début ne compense pas ce risque hypothétique, et mieux vaut de toute manière enseigner qu'interdire. Donc, jusqu'à le projet atteigne une complexité trop importante, je préfère la simplicité du mono module tout en faisant attention à ne pas mélanger les couches.

SCM

Même si vous êtes seuls, il vous faut quelque chose pour conserver et versionner votre source, ne serait-ce que par sécurité et pour avoir la possibilité de revenir en arrière. Git a beau être une star montant, je ne le connais pas, et je vais donc me contenter de conseiller subversion: simple, efficace, et non intrusif (pas de lock par défaut sur les fichiers).

IDE

Certains puristes vont certainement dire qu'un éditeur de texte suffit pour développer, mais à mon avis, on est loin d'une productivité optimale. Voilà à mes yeux ce que doit ABSOLUMENT faire un IDE:

  • intégrer les test unitaires : pouvoir les lancer facilement, et naviguer rapidement dans le code incriminé par un test rouge,
  • refactoring : c'est à mon sens l'outil ultime de productivité et de qualité. Sans aides au refacto il est trop facile, par manque de courage ou de temps, de ne pas faire des changements pour clarifier le code. Pourquoi renommer une classe si ça nous prend 10mn de faire le tour de l'appli pour trouver ceux qui l'utilise? Pourquoi extraire une super classe et centraliser du comportement si c'est un long travail fastidieux de copier/coller? Voilà pourquoi je pense qu'il est juste indispensable qu'un IDE intègre un certain nombre de refactorings assistés
  • auto-complétion, coloration, indentation: c'est la base, mais il est bon de le rappeler
  • navigation rapide dans le code: il doit être possible d'ouvrir rapidement des types ou des fichiers, mais aussi depuis une classe par exemple d'aller directement dans le code d'un objet qu'elle inclue.

Il y aurait être d'autres choses à ajouter, mais c'est déjà pas mal. Les trois IDE les plus connus du monde java (Eclipse, NetBeans, Intellij Idea) assurent tous ces fonctionnalités en plus d'une intégration à Maven indispensable dans notre cas. Je ne vais pas rentrer dans des débats religieux sur lequel est le mieux, mais personnellement j'utilise Eclipse.

Intégration continue

Je pense que l'intégration continue doit être en place dans le premier jour du projet, il ne faut pas attendre de commencer à avoir des soucis pour la mettre en place. Le minimum est bien sur de compiler l'application et de faire tourner les tests.

Il existe maintenant pas mal de solutions gratuites, mais je dois avouer ma nette préférence pour Hudson, grâce à son esprit "on déploie et ça marche". C'est très simple à mettre en place, il marche très bien avec Maven, et il peut être étendu à souhait avec pas mal de plugins. Que demander de plus?

Les technos

Bien, nous avons la base pour commencer à développer, c'est bien, mais ça ne nous dit pas quels frameworks utiliser pour bâtir notre application web. Au risque de spoiler un petit peu, je vous annonce tout de suite que je ne vais pas conseiller JEE, même en version "simple" en n'utilisant que servlet/jsp.

Restlet

Voici un framework qui mériterait un billet à part entière, mais je vais essayer de faire un résumé. Le but de restlet est de servir de base pour produire et consommer des ressources conformément à l'approche Rest. Ce qui est bien avec ça, c'est que l'on peut commencer très simplement, en faisant une application "à l'ancienne" avec des pages html entièrement générées côté serveur, puis commencer à si on veut à faire plus du RIA, avec GWT, Flex, Dojo, peu importe, les ressources restent les mêmes, on négocie juste une représentation différente.

Comme je le disais, Restlet est très simple à mettre en place, pas besoin de conteneur de Servlet ou autre, il peut démarrer son propre serveur web en une seule ligne de code. Les ressources et la configuration se fait également entièrement dans le code, avec quelques recours très discret aux annotations. Bref, Restlet est une base idéale pour toute application web: il est multi-paradigme, peut grossir en même temps que votre application sans vous forcer une grande complexité dès le début, bref, je suis fan. Ah vous de choisir au début si vous voulez faire une application à l'ancienne, du GWT, du flex etc etc, Restlet supporte tout le monde de toute manière. Suivant ce que vous avez décidé, vous pouvez ensuite par exemple utiliser Freemarker ou Velocity pour générer la représentation html de vos ressource selon une approche MVC bien connue.

Hibernate

Ah voilà un choix plus discutable n'est-ce pas quand on cherche à définir les frameworks les plus simples pour démarrer n'est-ce pas? Le plus simple pourrait-on me dire, serait de directement se connecter à la base, et de faire nos requêtes. Le soucis avec cette approche, c'est que jamais elle ne sera capable de gérer correctement une grande complexité. On se retrouvera nécessairement avec du code mort, de la duplication et une très faible réutilisabilité du code. Ceci dit, il doit y avoir plus simple qu'Hibernate non pour accéder à nos données? Sûrement, mais là je vais devoir avouer que je suis complètement perverti par DDD, et je ne conçois pas de ne pas d'abord penser objet, tester, puis seulement ensuite de faire apparaître la base. Seul un mapper O/R par metadata mapping permet d'utiliser cette approche à 100% , et hibernate est la meilleure solution open source gratuite que je connaisse pour atteindre ce but. Ah mes yeux, et pour une fois, l'effort d'écrire et maintenir tout ce XML me semble complètement être compensé par la valeur: pouvoir écrire un modèle du domaine testable et indépendant de toute considération technique. Le point discutable est sans doute, dans le cadre d'une application juste CRUD, est-ce que ça vaut le coup de sortir l'artillerie lourde? Ma réponse habituelle est que je n'ai jamais connu en 7 ans d'applications qui faisaient simplement du CRUD, donc j'ai le sentiment que ce n'est pas la règle mais le cas particulier. De plus, comment savoir à l'avance que l'application ne fera QUE du CRUD quand on la commence?

Quelques remarques

Il y a bien entendu des critiques à émettre sur le choix des technologies de base, notamment sur la productivité. Il y a peu voir pas du tout de travail prémaché dans ce que j'ai proposé, pas de composants déjà utilisables rapidement, ou de scripts pour générer rapidement les "échafaudages", sans doute parce que je ne suis fan d'aucunes des technologies proposant ces options, car trop de choix me déplaisent dedans (Ruby on Rails et Grails sont très contraignants sur pas mal de points, tant ils font de choix pour nous, Wicket, JSF and co sont orientés composants et modèle par page et ne tirent pas partie à mon avis des avantages du web; Spring MVC est déjà plus sympa, surtout en version 3, mais c'est déjà beaucoup plus lourd que Restlet...)

jeudi 18 juin 2009

Ruby

Voilà quelques temps que je m'intéresse à la nouvelle star montante des langages de programmation : Ruby.

Etant donné que je ne suis pas du tout encore un expert sur le sujet, je ne vais pas m'éterniser, mais laissez moi partager quelques remarques avec vous. La communauté Ruby se vante, souvent à juste titre, d'utiliser un langage très expressif, piloté par les bonnes pratiques de développement. Cependant, je n'ai pu m'empêcher de noter quelques éléments qui, je trouve, contredisent cette affirmation.

Le premier constat vient tout simplement des méthodes de conversion, les classiques toString, toInt etc etc que nous pourrions trouver dans d'autres langages. Plutôt que d'utiliser des noms complets, en ruby nous allons trouver des to_s, to_a, to_i. Pour un langage qui se veut expressif, je trouve ça excessivement choquant d'utiliser des acronymes pas nécessairement évident.

Deuxième constat, saviez vous qu'il existe une différence entre les méthodes eql? et equal? L'un compare sur le type et valeur, et l'autre sur la référence. Différencier ces deux comportements juste par une convention de nommage très bancale me semble juste aberrant. Un débutant ne peut juste pas faire la différence, et même les plus expérimentés peuvent facilement se laisser tromper. Ruby se vante également d'être entièrement orienté objet, contrairement par exemple à Java ou C# qui font tout deux la différence entre des types primitifs et les types références. Cependant, les libs globalement fournies avec Ruby sont tout simplement noyautées de méthodes statiques. Pourquoi se venter d'être Full OO si c'est pour s'appuyer aussi lourdement sur une approche procédurale?

Enfin, dernière remarque, Ruby ne supporte pas la surcharge de méthode: le nom d'une méthode doit être unique dans une classe. Du coup, si on veut utiliser la surcharge, qui est tout de même très pratique, on doit accepter en fait un nombre variant de paramètres, et à nous de tester tous les cas d'appels que l'on veut gérer. La complexité cyclomatique générée par cette approche est juste énorme. La liste pourrait s'allonger encore, tant finalement le langage est l'interpréteur sont bourrés de "petits trucs" qui sont juste impossible à deviner et peuvent briser votre programme si vous ne les connaissez pas. Par exemple, j'utilisez un "gets" pour lire une entrée en mode console, et quand je me suis à passer un paramètre à la commande, ça ne fonctionnait plus. Le côté souvent "magique" de certaines parties de ruby brisent à mon sens le principe de moindre surprise, et le gets en est un bon exemple.

J'essaye de faire la part des choses bien entendu, et je n'ai essayé ici de citer ici que ce qui me semble être de vrais soucis, et non pas des habitudes provenant d'autres langages. Un langage qui vaut la peine d'être appris doit changer note manière de penser, et Ruby m'a effectivement apporté beaucoup, et je l'apprécie. Ceci dit, après un tel buzz, je ne peux pas m'empêcher d'être déçu par ces détails qui sont mines de rien, pas si insignifiants que ça.

mercredi 1 avril 2009

Le nombre de if comme signe de qualité

Voilà quelques temps déjà, en parlant du projet, un des membres de l'équipe ne venant pas vraiment du monde objet avait fait la remarque que ce qui l'étonnait le plus dans notre code, c'était le très faible nombre de if. Remarque intéressante, mais que j'oublie un peu et voilà qu'hier, j'entends la remarque de la part de quelqu'un d'autre, et concernant un autre projet. Cet après-midi, j'ouvre un projet que je suis censé faire évoluer, et je tombe sur bien peu de classes, mais avec beaucoup de méthodes un peu trop grosses et surtout bourrées de if. Non content d'induire une certaine difficulté à la relecture, la plupart de ces if en fait étaient la pour palier l'absence de concept. C'est à dire qu'ils servent essentiellement à tester la valeur de string et faire un traitement adéquat. Je ne sais pas à quoi cela vous fait penser, mais très personnellement ça m'a amené à l'esprit le refactoring d'école : "un switch est un polymorphisme manqué". Et c'est vrai qu'en essayant de faire apparaître de nouvelles classes avec les bonnes responsabilités, les if ont fondu, le design est devenu plus évolutif et "ouvert à l'extension", et le code beaucoup plus facile à relire.

Du coup, pour revenir au titre de billet, c'est presque à se demander si le nombre de if ne serait pas une métrique intéressante à mettre en oeuvre pour donner un indicateur de plus sur la qualité d'un projet. Le chiffre est bien sûr à mettre en perspective en fonction de la taille du projet, mais je pense qu'un faible nombre de if du coup aurait tendance à démontrer un design pensé en terme de responsabilités plutôt qu'en séquentiel.

mardi 24 mars 2009

La qualité, ça compte

Si vous lisez régulièrement ce blog, vous devez sans doute savoir que je développe depuis quelques mois maintenant dans un environnement full JEE5. J'ai eu l'opportunité tout d'abord de démarrer un projet de 0, puis de reprendre pas mal d'applications existantes.

Mon premier réflexe en commençant la nouvelle application, à part écrire un test, a été d'appliquer au moins les quelques patterns d'organisation de DDD, à savoir aggregate, entity et value object. J'ai pris tellement l'habitude de structurer mon domaine de cette manière que j'aurai d'ailleurs bien du mal à faire autrement. Bref, comme d'habitude ça a fonctionné et j'ai obtenu un modèle du domaine "taclant" correctement la complexité sans devenir illisible.

J'ai du ensuite reprendre d'anciennes applications également sous JEE donc, et je dois avouer que c'était la première fois que je m'essyais à cet exercice. Oui j'avais déjà travaillé sur des "brown fields", mais ils avaient tous en commun de s'appuyer intensivement sur la base et pas sur du "code". Du coup, ce que j'ai découvert en fait m'a "ouvert" les yeux encore plus sur l'intérêt des patterns décrit dans DDD. Car finalement, ce que j'ai eu à reprendre est globalement du code qui essayait d'utiliser les concepts EJB3, mais sans auncune structuration. Donc on se retrouve avec des DAO dans tous les sens, même pour récupérer des entités dépendantes d'une racine; on trouve carrément des références vers des ID plutôt que vers les entités réelles, des références croisées dans tous les sens, bref, je me suis retrouvé face à ce que tout que les concepts d'aggregate/entity/value objet essayent d'empêcher, tous ces problèmes qui font croire à pas mal de gens que l'objet, c'est imbitable.

Bilan de cette histoire:

  • et d'une, il y a toujours des choses à prendre dans DDD,
  • de deux, avant d'entrer dans des systèmes aussi complexes que peuvent être les différents serveurs JEE, et se vanter de faire des supers architectures , il faudrait se concentrer sur qui compte réellement : le code. Je ne veux pas faire une généralité de cette règle, mais je ne compte pas le nombre de tutoriaux/messages de forum/newsgroup etc etc ou j'ai pu constater ce phénomène de "branlette sur l'architecture" alors que le code montré en exemple était tout simplement dégueulasse.

L'architecture n'est pas un paliatif à du code de piètre qualité.

mercredi 25 février 2009

Perf4j

Bon aujourd'hui, je ne vais pas vous infliger un grand discours philosophique. Je voulais juste partager ma petite découverte de la semaine: perf4j, dont la philosophie se résume à cette phrase:

Perf4J is to System.currentTimeMillis() as log4j is to System.out.println()

L'idée est donc qu'il doit être aussi facile d'introduire du code de profiling que du code de logging. Donc à la manière que Logger.getLogger, nous allons récupérer un StopWatch dont l'implémentation dépend de votre framework de logging favoris. L'idée est de générer des traces de performances enregistrées par votre système de log habituel. Du coup le système est entièrement configurable au même endroit que le logging. Si jamais vous trouvez ce code trop envahissant, nativement il est possible d'utiliser aspectJ ou SpringAOP pour le tisser à votre place.

Perf4j est ensuite livré avec un outil en ligne de commande capable d'analyer ces traces, et de proposer des aggregats et des graphes. En poussant la configuration un peu plus loin, on peut même du coup avoir des informations de performances en temps réel via jmx/servlet/etc etc.

Perf4j a mon sens ne remplace pas complètement un bon vieux profiler quand il s'agit d'identifier les problèmes de performance d'une application, mais son extrême simplicité et sa capacité à fournir des statistiques sur le code même en production m'ont assez plu.

J'avais un petit besoin de profiling, et j'ai été heureux de trouver un outil simple pour ça.

mardi 3 février 2009

JPAHAHAHA

Ceci est dans la continuité de ce que je disais sur EJB 3. Je continue ma découverte de ce petit monde EJB 3/JPA, et mon sentiment pour conclure est que pour faire cette norme, il a suffit de prendre hibernate, et de lui enlever tous les concepts qui faisaient qu'il supportait relativement facilement DDD

Non content donc de ne pas supporter les collections de types primitifs ou de composants, en plus JPA ne supporte pas le delete-orphan. Leur super conseil à ce niveau là est donc de dire "bah appelez un session.remove(childASupprimer)". Il faudra sans doute leur faire savoir que tout le monde ne fait pas des transactions scripts, et que certains d'entre nous aimeraient pouvoir faire confiance au mappeur O/R pour synchroniser de manière transparente leur modèle du domaine. Du coup je me retrouve obligé d'exposer dans mon entrepôt d'objets parents une méthode pour supprimer les fils. Adieu persistence ignorance.

mardi 20 janvier 2009

norme EJB 3, je te hais

Bon avec un titre pareil, je pense que vous m'avez déjà compris.

Ca va faire un mois que je travaille sur un projet s'appuyant lourdement sur la norme JEE 5. J'étais pourtant parti d'un bon pied, en me disant qu'il était de toute manière possible de faire de bonnes choses avec. Le soucis, c'est que je vais de frustration en frustration, et notamment au niveau mapping O/R. Même si JBoss est le serveur d'application utilisé, et que donc, le persistence est assurée par Hibernate, la directive d'architecture est de ne se baser que sur la spécificaiton EJB 3 pour pouvoir déployer sur n'importe quel serveur. Le soucis de cette spec, c'est qu'elle est incroyablement limitée comparée aux possibilités d'hibernate.

Je ne vais pas tenter une liste exhaustive, mais voici quelques une de mes plus grandes frustration:

  • Pas d'API de requête, tout doit passer par EJB QL. Tant pis pour la génération de requête générique et l'intégration aux outils de refactoring.
  • Par défaut, utilise les annotations pour définir le mapping, cassant à mon sens le concept de Persistence ignorance,
  • Ces fameuses annotations sont beaucoup moins intuitives qu'Hibernate
  • Si jamais on veut se passer des annotations, par défaut il faut mettre le mapping dans un seul gros fichier xml bien boulimique. Très surprenant quand on sait que JBoss supporte tout à fait la détection à la volé de tout ce qui est *.hbm.xml
  • La norme ne supporte pas les collections de types primitifs ou de composants, et là, c'est juste inadmissible. Oui, pas de collection de String par exemple dans vos objets, interdit ça.

lundi 26 mai 2008

Piloté par le stress

Voilà un certain temps que je n'ai pas publié quelque chose, et il y aurait tant à dire, mais je vais me contenter de parler du danger que je crois voir dans une gestion "classique" d'équipe de développement.

Lire la suite...

mardi 22 avril 2008

Démonstration

En me documentant sur Sping MVC, je suis bien entendu tombé sur le tutorial "official", contenant entre autre ça.

C'est tellement une illustration de ce que je disais il y a quelques temps que ça en est presque risible.

Alors pour résumer, je trouve assez fantastique qu'en un seul petit exemple simpliste on réussisse à voir apparaitre

  • un modèle du domaine anémique
  • des DTO portés au rang d'objet métier servant de cœur au système
  • une conception procédurale: le service héberge les traitements de A jusqu'à Z
  • de la surcomplexification: utilisation d'une interface implémentée une seule fois, couche de service inutile dans le contexte.

Je sais, ces éléments sont plus ou moins liés, mais laissez-moi être un peu théâtrale.

Bref, je le répète, une magnifique démonstration de ce que je n'aime pas voir dans un projet et que pourtant, je croise à chaque coin de rue.

mardi 8 avril 2008

Linq

Je disais en février que j'avais un peu de mal encore à voir comment utiliser Linq. Depuis, de l'eau a un peu coulé sous les ponts, et des articles intéressants ont commencé à voir le jour à droite à gauche donnant une orientation intéressante à cette techno. A mon tour donc d'y aller de ma participation.

Lire la suite...

mercredi 2 avril 2008

Chose promise...

Voilà quelque temps, j'ai promis à quelqu'un je ne nommerai pas (mais il se reconnaîtra j'en suis sur) de faire un billet/article sur entity framewok.

Lire la suite...

Mieux vaut en rire...

Au détour du net, on trouve de même des choses assez marrante, après le manifeste agile, voici donc le waterfall manifest. Je pense que finalement il n'y a pas meilleur résumé :)

Sinon au détour de ce site, on trouve des liens croustillants comme le asshole driven development, qui pourrai être mon plus grand fou rire de la journée si je ne l'avais pas déjà expérimenté trop de fois.

vendredi 21 mars 2008

Il faut que cela se sache

Je fais juste rapidement un petit lien vers un billet de Fabien pour faire passer l'info que nous avons découverte hier: la différence colossale de perf entre le driver Microsoft pour Oracle et le driver fourni par Oracle sur les requêtes paramétrées.

Peut-être que nous avons manqué quelque chose en route qui expliquerait cette différence, mais en tout cas je n'en ai pas l'impression.

lundi 17 mars 2008

NHibernate(encore lui) et identité

J'en parlais donc il y a quelques instants, mais me revoici pour un autre petit billet sur ce bien bel outil qu'est NHibernate. Ce coup-ci, laissez moi vous entretenir du principe d'identité des entités.

Lire la suite...

NHibernate et cache de second niveau

Voilà un petit moment que j'ai pas eu l'occasion d'écrire un peu ici. Ce n'est pas qu'il ne se passe rien, c'est que mon temps est un un peu accaparé par pas mal de projets dont j'espère bientôt pouvoir parler ici.

Lire la suite...

- page 1 de 2