Catégories : Expertise DSIPar Tags:

Combien de fois ai-je entendu des débats sans fin sur les avantages ou les risques de la génération de code. Les développeurs débattent en toute bonne foi sur ses vertus et ses dangers avec une passion qui frôle parfois le niveau des guerres de religion.

La vraie question

Après avoir passé 20 ans dans le logiciel, je peux affirmer avec détermination que cette question est mal posée. La question n’est pas ‘devriez-vous’ ou ‘ne devriez-vous pas’ générer du code ? La question serait plutôt de savoir quand et comment ?

Consciemment ou pas, en tant que développeur, vous avez certainement déjà utilisé les mécanismes de génération de code à différents niveaux avec les outils que vous utilisez.

Voici quelques exemples dans le monde .NET :

  • ASP.NET est lui-même un générateur de code. Des classes intermédiaires sont générées et compilées à la volée.
  • Le concepteur de Windows Forms est un générateur de code. Il crée des classes C# ou VB.NET à partir de l’éditeur de formulaires graphiques.
  • Le concepteur XAML designer est un générateur de code. Il crée des fichiers . G cachés de l’éditeur graphique XAML.
  • La class XmlSerializer, utilisée massivement pour la sérialisation XML, est un générateur de code implicite. Elle crée du code et le compile pour améliorer la performance de la sérialisation.
  • Certains fichiers de Visual Studio comme les .RESX (fichiers de ressources) ou .SETTINGS (fichiers de configuration) sont utilisés par l’environnement de développement pour générer des classes utilitaires.
  • Les fichiers .EDMX d’Entity Framework (Entity Data Model) sont utilisés pour générer des classes ObjectContext d’Entity Framework.

En réalité, la génération de code n’est jamais un problème tant que :

  • elle est transparente (vous ne savez même pas que vous l’utilisez),
  • vous faites confiance au générateur (et vous n’avez pas besoin de vérifier ce qu’il génère).

Les avantages de la génération de code

Pour comprendre quand vous devez l’utiliser, commençons par souligner les bénéfices qu’elle peut vous apporter. Correctement utilisée, la génération de code vous permettra d’automatiser des tâches de programmation qui devraient être faites à la main. Ce n’est pas très différent de n’importe quel processus d’automatisation de tâches répétitives.

Par conséquent, quand la programmation devient-elle répétitive ? Surtout lorsque vous avez besoin de suivre une structure et d’implémenter des motifs (”patterns« ) de la même manière pour un nombre significatif d’éléments.

En règle générale, quand vous implémentez une application métier, vous avez plusieurs entités métiers et avez besoin de structurer votre application en couches. En faisant cela vous aurez besoin de mettre en œuvre l’accès aux données et la manipulation des méthodes, la structure du modèle objet métier, les couches services et aussi des éléments de l’interface utilisateur ou des rapports qui reproduiront les mêmes schémas d’implémentation et les mêmes principes.

Coder cela à la main prend non seulement plus de temps mais c’est une source d’erreurs induisant un risque de qualité hétérogène et une dette applicative plus élevée.

Si cela est si évident, comment se fait-il que des développeurs chevronnés puissent le contester ?

Quand la génération de code ne fonctionne-t-elle pas ?

Le vrai problème réside dans le fait que générer du code approprié avec un niveau de flexibilité suffisant et une réelle capacité d’évolution est complexe, et la plupart du temps, ce point est sous-estimé par les développeurs, même les plus intelligents. Par conséquent certains développeurs ont souvent eu des mauvaises expériences et en sont arrivés à la conclusion que la génération de code était une mauvaise idée.

Sur le terrain, on observe 2 scénarios principaux d’échecs.

Dans le 1er cas, le développeur a essayé de développer son propre générateur. Cela commence généralement lorsque le développeur remarque qu’il effectue une tâche répétitive et qu’il essaie de l’automatiser, ce qui semble intelligent à première vue. Mais quand la complexité augmente, ajuster le générateur avec des besoins plus riches devient plus chronophage que de coder à la main.

Si nous devions ajouter la maintenance du générateur de code dans le schéma des coûts, ils seraient sans doute bien plus élevés qu’avec le code manuel sur le long terme surtout si vous voulez un ensemble de fonctionnalités significatif et supporter les technologies dès leur disponibilité.

Ensuite, le développeur est généralement pris au piège avec comme alternative soit d’investir plus de temps dans le générateur, soit de considérer ce qu’il a fait comme une action ‘one-shot’ et essayer de maintenir directement le code généré. Pas de chance ! Les 2 approches sont des impasses.

L’investissement dans un générateur puissant et flexible croit de façon exponentielle et le développeur n’a aucune chance de maintenir le rythme de l’innovation technologique à moins que cela ne devienne son unique objectif de développement.

Maintenir le code généré à la main est également une mauvaise idée. Une base de code généré est toujours plus importante qu’une base créée manuellement, donc il est contre-productif d’utiliser un générateur si vous devez maintenir le code généré. Votre dette de maintenance sera accrue.

Le second scénario est l’utilisation d’un générateur de code limité. Qu’est-ce qu’un générateur de code limité ?

Il y a différentes façons pour un générateur de montrer ses limites. La plus classique est le manque d’ouverture de beaucoup de générateurs de code. La majorité relève le défi de la complexité en réduisant vos options en tant que développeur jusqu’à limiter les possibilités pour le développeur. C’est pourquoi les capacités d’extension et de personnalisation doivent être étudiées en détail lorsque vous évaluez ce type d’outil.

De l’autre côté du spectre, il y a l’approche opposée basée sur des ‘templates’. La génération de code basée sur les templates est un mécanisme très simple et puissant pour mixer du code et du contenu. C’est typiquement ce qui a été utilisé pour la technologie “Active Server Pages”, en utilisant la syntaxe <% … %>, quand Microsoft a proposé sa 1ère approche dynamique pour le web.

Cela est très séduisant à première vue, car très ouvert puisque vous pouvez faire évoluer vos tempIates pour ajouter des fonctionnalités. Cependant, bien qu’utile dans certains scénarios, ce procédé pose des problèmes de complexité s’il est appliqué au cœur d’applications fonctionnellement riches. Ces générateurs de code apportent intrinsèquement une faible valeur dans la mesure où ils transfèrent la complexité dans les templates. Lorsque le code entre parenthèses pèse plus que les éléments de contenu, c’est un signe que vous êtes allé trop loin.

Une couche sérieuse de “Business Object Model” pour les applications professionnelles ne peut être générée avec des templates sans que ceux-ci ne deviennent très complexes. Au mieux, ces templates sont maintenables par un développeur ‘superman‘ qui les conçoit. Au pire, ils ne peuvent plus évoluer.

C’est exactement pour cette même raison que Microsoft a abandonné ASP qui fonctionnait pour des sites web simples et peu dynamiques et a développé la Plateforme ASP.NET. Cette nouvelle approche était rendue nécessaire pour une plateforme d’applications web plus riches et un niveau de maintenabilité approprié.

Les attributs d’une génération de code qui fonctionne

Avec toutes ces manières d’échouer dans la génération de code, comment réussir ?

De notre point de vue, les attributs clé d’une génération de code efficace pour les applications métiers sont les suivants :

  • Le générateur de code est fourni pour une équipe responsable et distincte de l’équipe qui développe l’application métier,
  • Idéalement, le générateur de code est maintenu par une société extérieure qui en a fait son métier et ses affaires,
  • Le générateur est suffisamment fiable pour que vous puissiez concentrer vos efforts de maintenance uniquement sur les éléments sources de la génération,
  • Le code généré reste lisible et suffisamment simple pour ne pas introduire un niveau de complexité supérieur au code manuel,
  • La génération de code des parties centrales et back-end (base de données et modèle métier) permet de maitriser la complexité à travers une modélisation puissante des concepts,
  • La génération de code basée sur les templates est uniquement utilisée sur les composants qui implémentent plus d’éléments visuels et de contenu que de logique métier, typiquement les composants frontaux tels que les interfaces utilisateur et les rapports.

Comme à l’accoutumée, n’hésitez pas à commenter de vos propres expériences.

Ne ratez plus aucune actualité avec la newsletter mensuelle de SoftFluent

Newsletter SoftFluent