jeudi 4 août 2011

Séparer logiques et données

Je vais vous parler d’une manière de coder des logiques de décisions qui peut dans certains cas s’avérer vraiment désastreuse.

Beaucoup de développeurs ont constaté qu’il esit très pratique d’utiliser des tables de base de données relationnelles pour stocker des paramètres d’une application. Ainsi un simple script écrit par exemple en SQL suffit pour les mettre à jour. Il est bien sûr préférable, plutôt que de se satisfaire de scripts SQL de mettre au point une IHM dédiée à l’administration de ces paramètres, mais ce n’est pas toujours indispensable.

Cette pratique peut parfois être la cause de difficultés insoupçonnées et insoupçonnables et être la cause d’incidents qui peuvent rester mystérieux durant des années, jusqu’à que la situation devienne insupportable.

Il se trouve d’ailleurs que lorsque mes clients me demandent un état des lieux ou un diagnostic cette pratique est souvent à l’origine des difficultés rencontrées.

Par exemple, j’ai évalué, il y a quelques années, un système informatique ou une dizaine d’applications différentes partageaient la même base de données.  Cette base comportait plusieurs centaines de tables et certaines de ces tables étaient des tables de paramétrage. Ces paramètres servaient en particulier pour paramétrer deux décisions prises par l’application. La première était relative à la tarification de produits et l’autre à la segmentation des clients. L’intérêt de cette base est d’être unique et cela devait en principe garantir la non duplication des données de référence ce qui peut parfois être une très bonne chose et ce qui dans ce cas s’est avéré particulièrement néfaste.

Dans notre cas, les IHM d’administration fonctionnelle étaient insuffisantes et de nombreux scripts SQL devaient être mis fréquemment en production pour corriger des incidents. Ces scripts SQL pouvaient être élaborés soit par les études informatiques, soit par les équipes d’exploitation informatiques en charge de la supervision et du support des utilisateurs.

Mais le vrai problème ne venait pas de là, le vrai problème est que le sens des paramètres fonctionnel s’est disloqué dans le temps au gré de la correction d’incidents toujours plus prioritaires les uns que les autres et au gré de la personne qui les corrigeait. Il faut préciser que les bases de données relationnelles ne sont pas spécialement conçues pour stocker des paramètres. Il faut aussi préciser que la valeur de certains de ces paramètres était codée sous forme numérique assez obscure au lieu d’utiliser un mot plus explicite issu du  jargon métier.
Pour comble de malheur, certains paramètres pouvaient avoir plusieurs sens variables soit en fonction du contexte utilisateur, soit en fonction de la plage de valeurs utilisée. Certaines tentatives de rétro-documentations ont été réalisées mais, devant une telle complexité, elles ont échouées.
Au bout de quelques années, l’application est devenue très difficile à maintenir et les recettes quasiment impossibles à réaliser. La correction d’un incident engendrant  systématiquement de nouvelles anomalies.
J’ai déjà évoqué le fait que cette base de données était partagées entre une dizaine d’applications c’est-à-dire qu’il était difficile de la modifier sans impacter l’ensemble des dix applications utilisatrices, autrement dit il était difficile de la modifier sans impacter la totalité des applications de l’entreprise utilisatrice.

Du fait de cette douteuse mutualisation et du fait de la longue durée de dégradation il n’y avait pas d’autre solution que des refontes coûteuses et assez longues à mettre en oeuvre.

Toute la difficulté a été de convaincre la direction de cette entreprise à investir dans une rénovation coûteuse et risquée. Elle avait tendance a préférer tout laisser en état.

Maintenant revenons à nos logiques de décisions et passons à la phase moralisatrice de cette fable, la morale étant toujours plus facile à écrire qu’à réaliser.

Que se serait-il passé si les logiques de décisions des tarifs et les logiques de décisions des segmentations clientèles avaient été codées sous forme de règles ou de tables de décisions ?

Tout d’abord cela aurait facilité la séparation entre les données et les logiques.


Le premier gain aurait été une meilleure lisibilité du paramétrage. Les bases de données sont faites pour stocker et retrouver des données, les bases de règles sont faites pour stocker et retrouver des règles. Quand on essaie d’utiliser une base de données pour stocker de la logique cela oblige à certaines circonvolutions qui rendent cette logique incompréhensible sauf pour la personne qui a créé ces circonvolutions et encore…

Cette séparation permet de simplifier la base de données en limitant le nombre de tables et le nombre de colonnes. Cela n’a l’air de rien mais quand la base de données devient un fourre-tout qui mélange logique et données, données de référence et données opérationnelles et qui multiplient les relations peu utiles la base de données devient vite lourde à gérer. Donc, deuxième gain une base relationnelle simplifiée plus facile à gérer et à partager.

Troisième gain, un peu plus difficile à comprendre et à admettre, la séparation logique et données permet de mieux gérer les exceptions. Je m’explique, il est  plus sûr de rajouter une règle que de rajouter une colonne dans une table relationnelle. Quand vous ajouter une colonne dans une table vous devez détecter et inspecter l’ensemble des requêtes qui utilisent cette table pour être sûr des conséquences de votre acte. Quand vous ajouter une règle vous pouvez lui adjoindre toutes les conditions utiles pour restreindre sa portée d’utilisation. Plus vous ajoutez de conditions plus vous diminuez le risque que cette règle soit exploitée à mauvais escient.

Le quatrième gain est une meilleure séparation des responsabilités, les personnes chargées des données s'occupent des données et les personnes chargées des logiques de décisions s'occupent des logiques décisions. Dès que le logiciel est un peu complexe ou un peu appelé à durer ou nécessite un niveau honnête de fiabilité, cette séparation des responsabilités prend tout son sens.

Pour résumé et en règle générale, mieux vaut séparer données et logiques. Si vous vous rappelez Edsger W.Djikstra et les principes de la programmation structurée cela vous dit sûrement quelque chose. Après, reste à traiter la question de comment cette logique aurait du être codée, cette question feraitr l’objet d’un autre billet.

1 commentaire:

  1. Il serait intéressant de citer d'autres distinctions qui produisent les mêmes effets.

    RépondreSupprimer