Anthony Patricio’s Blog

Foutaises, apprenez à les détecter

Posted in Actu / Anecdote by apatricio on Mai 15, 2009

Tout travail mérite le respect, la réflexion et le temps passé à concevoir et implémenter une solution ne peuvent être directement et gratuitement fustigés.

Il en va différemment lorsque les auteurs s’exposent eux-mêmes en lançant une information agressive et fausse (aka F.U.D) avec d’autres produits.

C’est ce qu’il s’est passé ici où l’on nous ressort un DataMapper basé sur des patterns anciens voire du millénaire passé comme commenté sur la page:

Honestly, the approach is old. I know that I’ve used similar approach going back to 1999 and it was old back then.

Reprenons depuis le début, le produit présenté n’a rien d’un ORM (Object Relationnal Mapping) dès lors qu’il impose d’énormes limitations au modèle objet, comme la non prise en charge de l’héritage et surtout qu’il ne propose pas de mapping… ben oui forcément. Ici il s’agit en fait d’imposer, via un framework, une organisation/une structuration du code dans des classes stéréotypées. L’idée est louable, toujours meilleures que d’avoir du JDBC pur non organisé et explosé partout dans un projet.

Cependant, c’est assez préhistorique et très franchement pénalisant sur beaucoup de points, lisons entre les lignes :

No lazy loading. Just eager loading because you can expect whatever you want during coding. Eager loading removes n + 1 queries.

Mouais, c’est un peu beaucoup n’importe quoi. Le lazy loading peut effectivement entraîner un soucis de n + 1 requêtes mais uniquement si le développeur est un lazy développeur (= développeur fainéant). Avec un ORM et hibernate en particulier, tout est fait pour pouvoir optimiser les modes de récupération de graphe d’objets. En passant « just eager loading » tend à forcer le chargement entier des graphes d’objets. Ceci est purement unitle et simplement consommateur de ressources. D’où l’existence d’une fonctionnalité comme le lazy loading qui permet de charger uniquement la portion de graphe nécessaire à un cas d’utilisation. Le lazy loading bouchonne le reste du graphe avec des proxies qui permettront eux-même le chargement transparent du reste du graphe en cas de nécessité, comprende? … la boucle est bouclée

an entity object which extends POJO

Comme le dirait un de mes bons amis:  « namuf ? » (= quoi?, kékidi? ou encore C’est une blague?). Pour faire court, simple et pour ceux qui n’ont pas tilté, un POJO est un objet pur, qui ne dépend d’aucun framework, encore moins technique. Un POJO est libre et peut être exploité par un client sans que l’on ait besoin de déployer une quelconque armada de jars de frameworks techniques au risque de se prendre une ClassNotFoundException.

Notre ami nous explique donc que les classes persistantes utilisées avec son framework doivent étendre une classe technique, présente dans son framework, classe qui se nomme très intelligemment POJO. C’est fantastique! Forcément et probablement sans même savoir pourquoi, il a du compléter son framework de convertisseurs:

built-in converter that can be used to convert a Java Object into a frontend String or a frontend String into a backend Java Object. The converter prevents data conversion from scattering different pages and layers.

Beh oui, les objets n’étant pas des POJOS, ils deviennent difficilement manipulables d’une couche à l’autre. Il faut passer par le bon vieux DTO, à savoir un POJO destiné essentiellement à des fins de manipulation de données. Et pour automatiser la transposition d’un « truc » (désolé ses trucs ne sont pas des POJOS pour moi) vers un DTO, que faut-il? Des convertisseurs, bravo. Il va forcément falloir gérer ces conversions de manière systématique, typiquement entre la couche service et la couche web.

Ces traitements sont coûteux en terme de développement et de maintenance, complètement inutile car ne contenant aucune plu value métier et forcément c’est vraiment contre productif. Mais non puisque notre ami nous affirme gratuitement:

High productivity compared to Hibernate.

Sans exagérer 70% de ce que dit l’auteur est faux et je vais arréter là, … euh, … aller une dernière pour la route, lisez attentivement le titre est les premiers mots du commentaire ici (écrit par l’auteur du framework lui-même. ):

No limitation

suivi de

There are no polymorphic queries

Comme c’est beau, il m’a convaincu!

Tout ceci ne veut pas dire que le framework est inutile ou mauvais, il ne répond simplement pas à un outil du spectre d’un ORM. En le aisant délibérement, l’auteur s’est tiré une balle dans le pied.

J’ai connu et connais encore plusieurs décideurs qui se laissent berner par ce type d’argumentation. Résultat: des applications qui utilisent des technos d’un autre millénaire (ce qui n’est pas grave) mais qui passent aussi à côté de technos pouvant résuire sensiblement les coûts de développement, de maintenance et d’évolution. Prenez une application de 50 tables avec 1000 requêtes SQL codées en dure, forcément pas le choix avec un DataMapper, il faut en coder une par cas d’utilisation. Ajoutez une colonne par ci par là lors d’une évolution, vous m’en direz des nouvelles…

Apprenez à lire entre les lignes et si vous êtes décideur sans être expert sur un sujet en particulier, déléguez à un de vos petits gars passionnés. Il vous fera gagner beaucoup d’argent à terme, croyez-moi. De même, méfiez-vous toujours des software marabous qui vous vendent une bidouille propriétaire  sortie du chapeau et qui vous certifie qu’elle est bien meilleure que les frameworks les plus robustes, matures et éprouvés.

Tagged with: , , ,

Comparer des pommes avec des oranges.

Posted in Actu / Anecdote by apatricio on Mai 14, 2009

Comparer des pommes avec des oranges est-il si stupide que cela?

Cette phrase amplement utilisée pour signifier que deux sujets ne peuvent être comparés entre eux est-elle réellement pertinente? Pour ma part, les affirmations absolues n’ont pas leur place dans ce monde, tout est question de contexte. Il est ainsi intéressant de comparer des pommes avec des oranges dans différents contextes comme la nutrition ou le goût.

Il y a quelques semaines, j’ai vérifié et corrigé une application destinée à comparer des outils de persistance d’objets java. Il y avait trois produits: un ORM mystérieux couplé à une BDD relationnelle et 2 Bases Objet.

Cette expérience fût l’objet de longs débats plus sémantiques et méthodologiques que techniques entre l’étudiant (préparant son doctorat) et moi-même qui devais valider son code et ses mappings. Au delà des résultats des tests, ce qui m’intéressait était de permettre à l’étudiant de prendre du recul et si cela ressortait dans sa dissertation alors mon objectif serait atteint. Pour lui faire entendre raison il m’a fallu ruser et utiliser une autre comparaison, place aux engins motorisés.

S’il fallait comparer une moto, une formule 1 et un 4×4, beaucoup de questions me viendraient à l’esprit, et malheureusement l’étudiant en question a foncé tête baissée dans le code sans se les poser:

Qui pilote les engins?

  • une personne sans permis
  • une personne avec une expérience significative pour chacun des véhicules

L’expérience semble nécessaire, malheureusement l’étudiant n’avait pas de réelle expérience pratique et, oh mon dieu!, n’a fait que survoler les guides de référence. Résultats: des erreurs graves un peu partout. Après une première passe sur ces erreurs grossières, les performances étaient déjà 2 à 3 fois meilleures.

Où tester les véhicules ?

  • sur un terrain neutre, très difficile à définir ?
  • sur un circuit ?

Tout dépend de l’objectif du test et de l’utilisation attendue par les destinataires du test. Admettons dans notre cas un test sur piste pour tester la vitesse pure des engins, en ligne droite, courbe, blah blah. Ici, le modèle Java utilisé avait du sens, tous les types d’associations étaient présents, ainsi que l’héritage. Petite chose irritante cependant, au lieu de se pencher sur un listing des fonctionnalités de chaque outil, le test cible les performances dans des cas d’utilisation de type batch. Les connaisseurs comprendront de suite le soucis: on ne choisit pas ce type d’outil pour faire des insertions/extractions massives de données mais bien pour permettre de concevoir une application qui nécessite une modélisation orientée objet.

Autorisation de prendre des raccourcis ?

  • Seul le 4×4 est capable de couper à travers champ pour le test
  • Alors que la formule 1 n’y survivrait pas.

Dans ce cas il semble nécessaire d’expliquer que le 4×4 dispose d’un avantage certains, non négligeable sur ces concurrents.

Si tous les véhicules peuvent prendre le raccourcis, la question se pose aussi, tout dépend de l’exhaustivité et de la lisibilité souhaitées. Ainsi un des deux fournisseurs de base objet a essayé de forcer l’étudiant à configurer son architecture autour du mode « stockage in-memory ». Oui mais voilà, des BDD relationnelles in-memory existent aussi, permettant des performances virtuellement explosives. L’étudiant a fait preuve d’impartialité et n’a pas accepté cette requête.

Quels pneus utiliser ?

Certainement l’aspect pouvant impacter le plus les résultats. Utiliser des pneus en mousse pour la formule 1 invaliderait l’ensemble des tests. De nombreux points techniques relevant de ce domaine ont du être rectifiés dans le code. Dans le cas ORM + BDD relationnelle, ce n’est pas l’ORM qui est testé, c’est bien l’ensemble. Il semble donc intéressant de comparer les résultats avec 2 BDD relationnelles différentes.

Épilogue: après différentes corrections et optimisations de bon sens (pas de triche genre cache de second niveau expressément tunné pour les cas d’utilisation), tous les tests (une 15ene) tournent entre 4 fois et 40 (oui 40!!!) fois plus vite.

Conclusion: même si la solution ORM/BDD relationnelle s’en sort une fois de plus grandie, je persiste à penser que, comme la quasi totalité des comparatifs axés uniquement sur la performance, ce test est un nième benchmark peu utile. Posez-vous toujours et en priorité la question de votre contexte d’applications d’entreprise. Pensez d’abord fonctionnalités, pérennité et réputation des produits. Si un produit est réputé et massivement utilisé, c’est déjà un gage de sécurité.