mardi 30 septembre 2008

Bonnes pratiques PHP : faut-il privilégier les frameworks ou les moteurs ORM ?

Voici ce qui pourrait fort bien devenir le premier troll de ce blog...

La question revient régulièrement ces dernières années, notamment du fait de l'apparition de frameworks toujours plus complets et perfectionnés. Avant d'émettre un quelconque avis, il convient de revenir sur certaines notions essentielles à la compréhension de la problématique :

Comment faisait-on avant ?

Si l'on se demande aujourd'hui quoi utiliser comme cadre à ses développements, du framework ou de l'ORM, il ne faudrait pas oublier comment l'on faisait avant l'apparition de ces couches de haut-niveau. Ni pourquoi on faisait autrement.

Oui, je suis bien en train de vous parler de cette époque antédiluvienne, de ce temps béni où l'on faisait n'importe quoi avec PHP, parce que l'idée même que l'on puisse faire mieux en termes de conception et de réutilisabilité ne nous effleurait même pas.

Certes, j'exagère un peu. Mais pas tant que ça. Puisque l'on avait tendance à repartir de zéro à chaque projet ou presque, et que l'on codait tout "à la main", on a usé et abusé de la permissivité de PHP.

Cela a conduit à un résultat curieux : à la fois une adoption massive de PHP, notamment de la part de non-développeurs, alors pourtant que le code produit était vraiment de piètre qualité, les performances et la sécurité totalement négligées etc.

Un premier effort vers la standardisation : les ORM

Dès lors que ces problématiques ont été identifiées, certains ont commencé à réfléchir à des solutions. La première réponse tangible proposée pour réduire la quantité de code à réécrire tout en systématisant certaines optimisations et certains contrôles de validité sur les données fut les ORM (Object/Relationnal Mapping). Très fortement liés à la programmation orientée objet, les ORM ont pour vocation de permettre la représentation (le stockage) d'objets directement dans une base de données.

Parfois qualifiées elles-mêmes de framework (pour compliquer un peu les choses), ces librairies permettent d'uniformiser l'accès aux données, en offrant en outre une certaine dose d'abstraction (possibilité d'interchanger les moteurs de bases de données auxquelles se connecte l'application sans devoir modifier le code). Plus encore, les ORM proposent d'automatiser certains traitements (simples) sur les données, comme la création, suppression ou modification d'enregistrements, y compris en tenant compte des contraintes relationnelles.

De ce fait, les ORM ont forcé les développeurs à prendre conscience de l'importance de la conception, notamment du design de la base de données. Celle-ci devant respecter les normes et nomenclatures imposées par la couche ORM, il devenait indispensable de prendre le temps de réfléchir à l'organisation de ses données avant de commencer le code.

Les Design Patterns : le trait-d'union entre ORM et Framework

Parallèlement l'apparition des ORM, qui en sont pour ainsi dire une émanation, un certain nombre de bonnes pratiques de conception ont été formalisées dans des "design patterns", sortes de modes d'emploi générique pour gérer dans son code des situations typiques.

Non pas d'ailleurs que ces design patterns soient apparus si récemment, mais c'est leur application au développement web, et PHP notamment, qui a été tardive. Pour l'anecdote, le design pattern "MVC" (Model-View-Controller, qui permet de séparer efficacement logique métier et présentation) date des années 70, mais semble n'avoir été découvert que vers 2004/2005 par les développeurs web.

Car en effet, un design pattern ne comporte pas de code : seulement du texte, présentant une solution générique, applicable à une problématique classique. Charge aux développeurs ensuite de l'implémenter au sein de leurs projets.

Le mix des deux : les frameworks

Le recours aux design patterns est devenu de plus en plus courant. Ce qui a impliqué la production d'un code assez important lors des implémentations les plus rigoureuses, à commencer par celle de MVC. Puisque les design patterns règlent des problèmes génériques, leurs implémentations ont également été génériquées.

Les ensembles constitués de ces implémentations de design patterns accompagnées d'une couche ORM ont constitués les premiers frameworks.

Et alors, que choisir ?

Framework ou ORM ? ORM ou JRLR* ? Comme vous vous en doutez, il n'y a pas de réponse universelle à ces questions. Encore que pour la deuxième, entre le recours à un ORM ou l'écriture "from scratch" de l'accès aux données, il me semble raisonnable de dire que la seconde solution ne l'est pas, raisonnable !

Pour ce qui concerne le choix d'un framework ou non, il faut prendre divers facteurs en considération :

  • La couverture fonctionnelle : l'intérêt premier de recourir à un framework est de bénéficier de ses composants pour éviter l'écriture de code inutile, et ainsi gagner du temps, beaucoup de temps (si l'on tient compte en plus du développement des tests etc.). Pour que l'intérêt d'adopter un framework soit attesté, il faut en premier lieu que sa couverture fonctionnelle soit supérieure ou égale aux spécifications du projet.
    • celle-ci est-elle suffisamment large pour englober l'ensemble des besoins inhérents à votre projet ?
  • La souplesse : si certaines fonctionnalités font défaut au framework, il sera nécessaire de les implémenter. Ceci ne doit pas être intrusif, c'est-à-dire que le code du framework lui-même doit rester inchangé, pour pouvoir profiter de ses mises-à-jour ultérieures.
    • Le framework offre-t-il la possibilité d'étendre ou de compléter ses composants ?
    • Si oui, cette possibilité permet-elle de garantir l'intégrité des sources d'origine du framework ?
  • Les compétences existantes : l'équipe doit posséder une maitrise suffisante du framework et être capable de l'utiliser de manière fluide (i.e. sans passer une heure et demie dans la doc 4 fois par jour pour pouvoir avancer à sa guise) pour réellement bénéficier de son emploi.
    • L'équipe dispose-t-elle de ses compétences ?
    • Ai-je le temps et/ou le budget pour la faire monter en compétence ?
    • L'investissement est-il à la hauteur de mon projet ?
  • Les contraintes de performances : un framework, c'est bien. Il peut faire gagner énormément de temps au développement. En retour, il en fera assurément perdre à l'exécution. Mathématiquement, plus on automatise de traitements, plus ils seront lents. Dans certains cas extrêmes, on peut d'ailleurs signaler que même un ORM peut s'avérer trop couteux en performances.
    • Puis-je m'offrir les quelques centaines de millisecondes de surcharge par page que m'imposera un framework ?
Bien sûr, cette liste n'est pas exhaustive, mais une fois que l'on a répondu à ces questions, on peut déjà se rendre compte, dans les grandes lignes, de la pertinence ou non de l'adoption d'un framework pour un projet donné.

* JRLR = Je Réinvente La Roue :)

Conclusion

La conclusion de tout ceci est simple : les frameworks modernes, orientés objet, représentent une avancée considérable pour PHP. Pour autant, les adopter de manière systématique, quels que soient les projets à porter, ne me semble pas être une bonne idée.

Les ORM ne sont pas morts, et peuvent rendre de grands services, tout particulièrement lorsque la machinerie déployée par un framework est sans rapport ni par la taille ni par les fonctionnalités avec un projet donné.

Une solution intéressante pour conserver une certaine uniformité des pratiques pourrait être de recourir à un framework dont la couche ORM peut être utilisée de manière autonome, ou encore d'implémenter un ORM donné dans un framework sous forme de plugin.

2 commentaires:

jb.boisseau a dit…

"Pour l'anecdote, le degin pattern "MVC" (Model-View-Controller, qui permet de séparer efficacement logique métier et présentation) date des années 70, mais semble n'avoir été découvert que vers 2004/2005 par les développeurs web."

Euh, Struts, ça date de 2000 quand même...

Gauthier Delamarre a dit…

un point pour toi JB. J'avoue que je ne savais pas exactement quand ce motif avait été introduit dans les frameworks web Java, même si je sais bien qu'il l'avait été depuis longtemps dans les applications classiques Java.

J'aurais également pu parler de Python, avec son framework Zope qui propose également une implémentation de MVC.

En employant "semble n'avoir été découvert", je parlais de l'adoption massive du concept, mais ma phrase été ambiguë.