Architecture logicielle

How to organize a business layer ?

One of the main questions I had when I started my career was « where I can put the business source code ?« .

In the famous MVC pattern, there is no mention about the business layer. Moreover, most of the framework does not speak about the business layer.

This presentation, created for a lightning talk in the software craftsman Meetup of Raleigh in july 2014. Aimed to give a simple and quick answer to this question.

Publicités
Architecture logicielle

L’entropie logicielle, pourquoi la dette technique ne fait qu’augmenter ?

La deuxième loi de la thermodynamique, dans ses principes, énonce que la désorganisation d’un système fermé ne peut pas être diminuée, mais seulement rester inchangée ou augmenter. Une mesure de cette désorganisation est l’entropie. Cette loi semble aussi s’appliquer aux systèmes logiciels; quand un système est modifié, sa désorganisation, ou entropie, augmente systématiquement. Cela est connu sous le terme d’entropie logicielle.
Ivar Jacobson (traduit depuis l’anglais)

Entropie logicielle et dette technique

L’entropie logicielle est un principe intimement lié à la notion de dette technique. Commençons par définir celle-ci, il s’agit de l’ensemble des coûts cachés qui grèvent la rentabilité d’un logiciel :

  • Le coût lié à la perte de productivité des développeurs face à un code source incohérent, inutilement complexe ou de mauvaise qualité : perte de temps pour comprendre le fonctionnement du programme et rechercher de l’information.
  • Le coût lié à la correction de bugs : perte de temps pour corriger des dysfonctionnements (si cela touche un utilisateur final, il y a en plus une perte d’image pour le logiciel).
  • Le coût de modification du code source : le logicielle devient de plus en plus difficile à modifier sans effet de bord (défaillances en cascades sur d’autre partie du logiciel).

Ces effets sont cumulatifs : l’ajout d’une fonctionnalité provoque un effet de bord, menant à une défaillance difficile à retrouver à cause de l’incohérence du programme…

Par ignorance, la dette technique est malheureusement rarement prise en compte.Mais aussi par le fait qu’évaluer la perte liée à la dette technique est un exercice complexe : les coûts sont liés à une perte de productivité et donc très difficiles à évaluer. Enfin corriger et prévenir la dette technique (améliorer le code source) est souvent considéré comme un investissement inutile car n’apportant aucune fonctionnalité supplémentaire, tout en pouvant ralentir le projet en consommant du temps de développement.

Pourtant, imaginons que vos développeurs passent 2 heures par semaine à chercher “comment faire” et à corriger des défaillances sur des logiciels existants. Multiplions ces heures par le nombre de semaines travaillées dans l’année (~44) nous obtenons 88 heures, soit 2,5 semaines de développements (journée de 7 heures). Pour une petite équipe de cinq personnes, la perte est de 3 mois hommes ! Avec l’hypothèse d’un coûts salarial de 4000€ mensuel, la perte se chiffre à 12 000€ par an ! Alors que nous avons une toute petite équipe et en sachant que le chiffre de deux heures par semaine est déjà très optimiste. Dans la majorité des cas vous pouvez le multiplier par 3 ou 4 (et appliquer le même multiplicateur sur vos pertes).

De l’autre coté le principe de l’entropie logicielle énonce que naturellement votre dette technique ne fait qu’augmenter avec la durée de vie de votre produit : l’ajout de fonctionnalités augmente la taille du code source et donc sa complexité. C’est pourquoi, sans contre-mesure concernant l’entropie logicielle, votre produit verra ses coûts de production et de maintenance augmenter mécaniquement jusqu’à atteindre un seuil où la rentabilité du logiciel sera remise en cause.

Si en France la terminologie consacrée parle “d’érosion de l’architecture logicielle”, la terminologie anglaise est plus parlante en utilisant le terme de “software rot” soit “niveau de pourriture” du logiciel.

L’entropie n’est cependant pas une fatalité grâce à un ensemble de bonnes pratiques d’ingénierie logicielle. Dans la suite de cette article nous allons nous intéresser à ces facteurs qui accélèrent ou au contraire ralentissent l’entropie d’un logiciel et donc sa tendance à générer de la dette technique. Enfin Les architectes, en tant que garant de la maintenabilité du logiciel sont très sensibles à cette notion (si ce n’est pas le cas, changez d’architecte), malheureusement trop souvent laissée de côté par les instances managériales.

Lutter contre l’entropie

Lutter contre l’entropie revient à lutter contre la nature même de l’évolution d’un projet logiciel, c’est pourquoi vous devez mobiliser vos développeurs pour les aider à combattre cette évolution.

La première mesure est psychologique, tout le monde a pû remarquer que si certaines habitations sont bien tenues, propres et rangées d’autres sont au contraire en désordre sale et où l’on n’y retrouve rien. Dans le logiciel c’est la même chose, vous pouvez avoir des développements propres et bien entretenus et à l’inverse des code sources complètement dégradés. Ainsi votre première ligne de défense contre l’entropie est vos développeurs : ils doivent y êtres sensibilisés et prendre soin de leurs développements.

Dans ce cadre, intéressant de parler de la théorie criminalistique de la vitre cassée (notamment mise en oeuvre à New York avec de très bon résultats), l’exemple donné est le suivant :

Imaginez un immeuble avec quelques fenêtres brisées. Si les fenêtres ne sont pas réparées, des vandales vont avoir tendance à briser les autres vitres. Et même pénétrer dans l’immeuble pour en faire un squat.

En effet, pensant que le bâtiment n’est plus occupé ni entretenu des vandales vont se sentir le droit d’en augmenter la dégradation. C’est un principe universel et je pense que toute personne a déjà fait l’expérience que le désordre amène toujours plus de désordre.

Le parallèle avec le milieu du développement n’est pas anodin. Un développeur travaillant sur un code source de mauvaise qualité se laissera aller sans faire d’effort pour améliorer la situation. Au contraire d’un développeur travaillant sur un code source d’excellente qualité : plus précautionneux, augmentera de lui même le niveau de son développement. Vous devez donc surveiller l’apparition de code de mauvaise qualité (vos “vitres cassées”) et le réparer au plus vite avant que la situation ne se dégrade. Il est à noter que travailler perpétuellement sur des codes de mauvaises qualités va gréver la motivation de vos développeurs diminuant d’autant leur productivité.

Pour aider à la détection de ces “vitres cassées” et transmettre cet état d’esprit au sein d’une équipe, les revues de code en groupe se placent comme des outils de choix. Il suffit d’être plus de deux personnes, de prendre un morceau de code source (si possible de l’un des participants) et le commenter collectivement pour proposer des améliorations (une revue de code doit aussi montrer des exemples d’implémentations de bonnes pratiques dans le code source). Attention, ces séance ne doivent pas être à charge pour le développeur dont le code est audité, les critiques doivent être constructives. La préparation de ces événements peut être réalisée par un architecte logiciel dans un but pédagogique, ou auto-organisées entre développeurs. Bénéficier du regard d’autrui sur un code source est l’une des meilleure façon de progresser.

De façon plus opérationnelle, la méthode de lutte contre l’entropie logicielle passe par du “refactoring”. C’est à dire améliorer constamment le code source en factorisant les processus similaires : la duplication de code étant l’un des facteurs accélérant le plus l’entropie logicielle. Afin de ne pas introduire de régressions fonctionnelles pendant cette étape, les tests unitaires sont indispensables. Si votre logiciel n’est pas testé, vous pouvez démarrer au fur et à mesure des travaux de refactoring en testant progressivement le code source. L’absence de test ne devant pas être une excuse pour ne pas exécuter ce type de travaux.

Supprimez aussi tout code inutile, un morceau de code source ne servant plus à rien doit être supprimé, le logiciel de gestion de version des sources gardant l’historique du code vous pourrez le récupérer à posteriori si nécessaire.

Enfin un dernier conseil pratique : dès qu’un bug est identifié, écrivez d’abord le test unitaire le provoquant puis corrigez le bug. De cette façon vous êtes certain qu’il ne se reproduira plus. C’est un bon moyen de démarrer une campagne de tests pour une application existante. Dîtes vous que non seulement vous remplacez la vitre, mais en plus vous installez un détecteur de bris de glace.

En terme d’architecture logicielle, la simplicité est votre meilleure alliée, un système simple est moins sujet à l’entropie et donc plus facilement maintenable. En découpant un logiciel en une série de composants indépendant vous transformez une application monolithique en un agrégat de modules simples travaillant de concert. Ces approches sont connues sous le terme d’Architecture Orientée Service.

Conclusion

L’entropie logicielle et la dette technique sont des sujets trop souvent ignorés et souvent mal acceptés : leurs réductions nécessitent une réflexion sur le long terme, qui n’est pas toujours en adéquation avec les besoins de mise sur le marché. Cette vision au long terme est cependant indispensable si votre business modèle repose sur le bon fonctionnement et la capacité d’évolution de systèmes logiciels.

Au niveau des outils, les serveurs d’intégrations continus pourront vous apporter une aide précieuse : en exécutant des tests par une analyse du code source, ces serveurs analysent la qualité du développement en temps réel, fournissant des retours de grande valeur aux développeurs pour savoir s’ils vont dans la bonne direction.

Enfin la mise en place d’une pratique rigoureuse de méthodes agiles d’architecture logicielle comme l’ “Emergent Design”, permet de construire des applications plus résistantes à l’entropie logicielle. Pour plus d’informations sur ce sujet, vous pouvez lire la série d’articles sur les architectures agiles.

Illustration issue de wikipedia


Si vous avez ce type de problématique, ma société : Ibsciss vous apporte un large panel de prestations sur ces sujets.

Architecture logicielle

Concepts de l’architecture logicielle : le design émergent

Cet article est le troisième article d’une série sur les architectures logicielles agiles. Il fait suite à une introduction sur les concepts de l’architecture logicielle et à une étude détaillée de l’architecture avant-projet “just enough up front design”.

Nous allons à présent vous parler du cœur de la pratique du design émergent (“emergent design” en anglais) : l’architecture pendant la phase de développement. Cette partie sera donc un peu plus technique que les précédentes, mais souhaite vous rester accessible même si vous êtes non développeur.

Définition de l’emergent design

Comme définie dans l’article d’introduction, la notion de design émergent vient du fait que l’architecture de votre application va être définie au fil de l’eau, pendant sa création. Ce concept a été appelé “simple design” au moment de sa définition au sein du mouvement de l’XP programming mais le terme de “simple” étant mal compris, il a été renommé en : “emergent design”.

Il se pratique via une série d’étapes : les développeurs codent une fonctionnalité A puis une fonctionnalité B. Après cela ils identifient les éléments communs à A et B pour les factoriser (cette étape est nommée “refactorisation”). L’idée est donc de supprimer toute duplication de fonction au sein du logiciel (éviter d’avoir un code qui fait la même chose à deux endroits différents). En cherchant à éviter la duplication et en suivant une série de bonnes pratiques, que nous vous détaillerons dans la suite de ce document, une architecture logicielle va progressivement se dessiner.

A ce point de l’article, je tiens à rappeler que cette pratique n’enlève en rien la nécessité d’avoir une phase d’architecture avant-projet (voir sur ce sujet l’article précédent). La différence se situant dans le fait que la phase d’architecture amont sera plus légère et définira une vision technique plutôt que le détail de la mise en œuvre. Un manque de rigueur dans les bonnes pratiques du design émergent, une équipe pas impliquée ou l’absence de vision technique seront des éléments pouvant conduire à la ruine de votre projet.

Bonnes pratiques de développement

Cette deuxième partie va s’intéresser aux “principes” permettant la mise en œuvre des architectures émergentes. Très fortement conseillés, ces éléments sont à garder en tête pendant la phase de développement. Ce sont les outils dont vont disposer les développeurs pour garantir la qualité de l’architecture.

Le point sur lequel est construit le principe des architecture émergente est la suppression des duplications, ce qui a donné naissance à l’acronyme DRY : Don’t Repeat Yourself (en français : ne te répète pas). C’est donc le premier point à respecter, systématiquement factoriser deux procédures similaires. Cependant cela doit se faire en respectant un ensemble d’autres bonnes pratiques listées dans la suite, permettant de garantir la bonne architecture du logiciel.

Vous devez faire très attention à respecter les principes d’une forte cohésion associée à un faible couplage. Le principe d’une forte cohésion signifie que vos modules doivent former un tout cohérent et spécialisé (un module de facturation ne doit pas gérer les utilisateurs). Le faible couplage indique la facilité avec laquelle un composant peut être remplacé par un autre ayant le même rôle (par exemple changer le système qui gère les paiements).

Votre code étant factorisé, il est amené à être réutilisé au sein de l’application, souvent par d’autres développeurs. C’est la raison pour laquelle une attention particulière doit être portée à la qualité et la consistance du nommage de vos API et de vos fonctions. Les termes doivent être explicites et spécifiques (MailSender plutôt que MailManager pour une classe d’envoi de mail). Et cohérent, c’est à dire prévisible : même sans avoir la documentation un développeur doit pouvoir deviner comment utiliser votre code source.

Les méthodes agiles ont un de leurs principes qui s’énonce ainsi :

Des logiciels opérationnels, plus qu’une documentation exhaustive

Cela n’a jamais voulu dire qu’il ne fallait pas documenter le code source, il faut simplement documenter ce qu’il faut mais pas plus. Un fichier expliquant simplement l’organisation de l’application en terme d’architecture sera d’une aide précieuse lorsqu’il faudra faire évoluer le logiciel. Pareillement, il ne sert à rien de commenter chaque ligne d’un code source, mais les parties complexes d’un logiciel se doivent d’être commentées pour en expliciter le fonctionnement.

Enfin, n’écrivez que du code dont vous allez effectivement vous servir. De la même façon qu’il ne sert à rien de sur-spécifier, l’écriture de code “au cas ou” (sur-développement) est inutile et peut être dangereux dans la maintenance du logiciel. Aussi limitez le code au strict nécessaire pour résoudre un problème donné. Il sera toujours possible de lui ajouter du fonctionnel manquant dans le futur. Dans le même esprit : supprimez tout code obsolète, ne laissez pas de code commenté. Dans tous les cas le code est sauvegardé par le logiciel de gestion des versions du code source, si vous en avez besoin dans le futur, vous pourrez le récupérer.

Méthodes de développement

Après avoir vu l’ensemble des principes qui servent de fondement aux designs émergents nous allons nous intéresser à la mise en pratique de ces concepts, soit par des méthodes permettant de vérifier qu’ils sont bien respectés, soit par des mises en œuvres pré-établies garantissant ces principes.

Tests unitaires, et pratique du TDD : Test Driven Developpement (Développement Dirigé par les Tests). Cette pratique est la plus importante de toutes dans les architectures émergentes. En effet les tests unitaires permettent de garantir qu’aucune régression n’apparaît lors des phases de refactoring. Le TDD veut que les tests soient écrits avant le code source, cela présente trois principaux avantages :

  • Vous ne pouvez pas oublier de tester un morceau du logiciel
  • Cela vous garantit de n’écrire que le code nécessaire : celui qui permet de passer les tests
  • Vous utilisez votre code avant même de l’avoir écrit, ainsi vous pouvez identifier des problèmes de conception avant même la création du code. Ce dernier point est nommé TFD : Test First Design (tester d’abord le design).

Après chaque ajout fonctionnel vous devez factoriser votre code, même après l’ajout d’une simple fonction vous devez vous poser la question de savoir si vous ne pouvez pas la factoriser avec du code existant.

Enfin, les Design Patterns vous seront d’une grande aide dans ce type de problématique. Ce sont des modèles de résolution de problèmes courants en ingénierie logicielle. Je vous conseille de bien connaître l’usage des principaux et réussir à identifier quand les mettre en œuvre. Attention par contre à ne pas sur-utiliser les design pattern, ce ne sont que des outils génériques et à ce titre ils ne peuvent pas répondre à toutes les problématiques.

Conclusion :

La pratique de l’architecture pendant la phase de développement demande une très grande rigueur dans sa mise en œuvre et un certain nombre d’outils à maîtriser. Malheureusement ces outils ne sont souvent pas enseignés dans les cursus d’informatique, et vous devrez faire attention à laisser un nombre suffisant de développeurs expérimentés dans chaque équipe de développement. La mise en place de coach inter-équipe peut aider à la mise en place de ces bonnes pratiques.

Pour conclure cette série d’articles sur l’architecture logicielle, nous terminerons avec la question de la réutilisation inter-projet de composants logiciels dans le cadre des architectures agiles.

Image issue de wikipedia

Architecture logicielle

Concepts de l’architecture logicielle : “just enough up front design”

Cet article fait partie d’une série d’article sur l’architecture logicielle. Il est la suite du précédent article : introduction aux concepts de l’architecture logicielle.

Nous allons parler dans cet article de la phase d’architecture en amont du développement. Comme indiqué dans l’article précédent, cette phase doit être justement dosée pour ne pas tomber dans les affres de la sur-spécification : elle doit définir la vision technique du projet, mais pas plus.

Nous commencerons par voir les objectifs de l’architecture logicielle avant d’expliciter les outils concrets pouvant être utilisés lors des spécifications, dans cet objectif d’en faire “juste assez”.

Les objectifs de l’architecture logicielle avant projet

Dans cette première partie je vous propose de découvrir la philosophie de la phase d’architecture au travers de son triple objectif : donner une vision technique, préparer la structure du logiciel et identifier les principaux risques.

Dans cette approche l’architecture logicielle se limite à définir l’objectif (la destination) en suivant un ensemble de règles de bonnes pratiques, mais sans détailler le chemin pour y parvenir. Dans cette optique l’architecture doit être porteuse d’une vision claire afin de correctement guider l’équipe de développement dans son travail.

En effet, comme indiqué dans l’article introductif, l’architecture amont ne doit pas entrer dans les détails de la conception, mais laisser les développeurs s’en emparer pour faire “émerger” l’architecture au fur et à mesure de l’avancement du projet. Cependant cette liberté se doit d’être bornée pour éviter des problèmes de cohérence au sein de la pile logicielle.

Un des principaux objectifs sera ainsi de définir les pratiques de développements et mettre en place une ligne directrice pour le projet. Cela se fera par le choix, en fonction des contraintes du projet, d’un framework (et/ou d’une plate-forme de développement), par le respect de standards de développement et la définition de bonnes pratiques.

Enfin, lors de la définition de votre architecture je vous invite à avoir en permanence la philosophie du rasoir d’Ockham en tête. Saint-Exupéry l’énonce ainsi :

Il semble que la perfection soit atteinte non quand il n’y a plus rien à ajouter, mais quand il n’y a plus rien à retrancher
Antoine de Saint-Exupéry

Ce principe exprime que les solutions les plus simples sont les meilleures, et je vous encourage à rechercher la simplicité dans vos architectures. D’un point de vue plus opérationnel nous pouvons le définir de la sorte :

Les architectures les plus simples sont les plus robustes.

Les outils de l’architecture logicielle

Dans la phase d’architecture, vous devez fournir à l’équipe de développement, une vision technique. Pour ce faire, voici concrètement les outils pour partager celle-ci.

L’utilisation d’UML est déconseillée, elle apporte une rigidité souvent malvenue dans ce type de travaux. Si vous regardez la façon dont vous représentez une architecture, vous verrez que des carrés et des flèches suffisent amplement et je vous invite à continuer dans cette voie d’une représentation simplifiée.

Vos documents d’architecture doivent être visuels et rapidement compréhensibles c’est pourquoi les diagrammes sont la forme la plus conseillée. Personnellement j’utilise les diagrammes suivants :

  • Domain model : il s’agit de représenter les différentes entités métier du projet, leurs rôles au sein du projet et leurs relations. Cela permet d’obtenir une bonne vue du fonctionnement attendu du logiciel et prépare la définition du modèle de données.
  • C4 diagramme : ce diagramme est souvent en réalité deux ou trois diagrammes à différentes hauteurs de vue au niveau logiciel, l’on distingue les niveaux suivants :
    • Contexte, définit l’environnement d’exécution du logiciel : quel sont les éléments avec lesquels il devra interagir (système d’authentification, de logs, etc.)
    • Container : quel sont les grands ensemble métier et technique du logiciel et comment interagissent-ils entre eux (système de facturation, création de document, gestion des usagers, etc.).
    • Composant : sous partie spécialisée d’un container (génération d’une facture, gestion des paiements, etc.)
    • Classes, ce niveau est optionnel et ne doit être utilisé que si il est indispensable de spécifier une implémentation.

A ces éléments, il est généralement ajouté un document texte dans lequel est précisé les éléments suivant :

  • Les spécifications fonctionnelles sous forme de “user stories (fiche wikipedia)”
  • Un glossaire des termes utilisés dans le logiciel
  • Une liste des risques identifiés
  • Les contraintes liées au logiciel
  • La plateforme et/ou le framework à utiliser
  • Un rappel sur les bonnes pratiques

Le rôle de l’architecte

Dans le cadre d’une architecture en “emergent design” l’architecte ne disparaît pas. Il va être en charge de deux aspects amont : limiter au maximum les malentendus et définir la vision technique à l’équipe de développement.

Pour limiter au maximum les malentendus, et préparer au mieux la phase de développement, l’architecte doit affiner les spécifications fonctionnelles en anticipant les questions que pourraient soulever l’équipe de développement. Il en cherchera les réponses auprès du client et/ou du chef de projet.

Pendant la phase de développement, il doit défendre sa vision, rechercher le feedback des développeurs, et les aider à architecturer le logiciel. Il prend alors un rôle de coach pour l’équipe de développement. Le travail d’un architecte ne doit surtout pas se limiter à la phase avant projet, mais réellement accompagner l’équipe sur la durée du développement.

Enfin je rappelle qu’il est très important pour un architecte de se maintenir à niveau, à la fois en élargissant son domaine de compétence via une veille active, mais aussi en continuant à pratiquer le développement afin de garder un sens de la pratique.

Le cas des systèmes complexes

Les systèmes complexes (ou anciens) nécessitent généralement une phase d’architecture d’avant projet plus conséquente. Cependant cela ne doit pas amener à retomber dans les problématiques du “Big Design Up Front” (voir l’article précédent pour plus de détail).

Dans ce cas de figure, la solution consiste à découpler massivement le logiciel : le considérer comme un ensemble de plus petits logiciels spécialisés. Il s’agit alors de définir une architecture de système d’information, seule est définie l’information circulant entre divers composants spécialisés et autonomes. Ces composants sont alors considérés comme des boites noires, et seule les API (les entrés / sorties) sont définies. Chacune de ces parties sera alors conçue en utilisant les mécanismes du design émergent associés à la pratique du “Just Enough Up Front Design”.

L’approche SOA (Service Oriented Architecture) est une mise en œuvre de ce type d’approche : le logiciel est découpé en un ensemble de services spécialisés qui sont composés les uns avec les autres. Le logiciel devient la somme de sous parties indépendantes.

La place de l’UX dans le processus d’architecture

Mon métier consiste principalement à traiter l’architecture d’un point de vue technique, mais l’UX (User eXperience) a une place très importante. Dans l’objectif de limiter les futurs malentendus dans le développement, il est important de faire intervenir ces éléments dans cette partie.

L’UX comprend toutes les interactions que l’utilisateur final aura avec l’outil, l’application ou le site. Les modifications que cela peut entraîner sur le logiciel font que cette réflexion doit être menée à peu près au même moment que la définition de l’architecture.

L’entrée en scène des UX designer se fait au moment où les spécifications fonctionnelles sont dégrossies et lorsque la vision du logiciel commence à se préciser. La phase de design sera l’occasion de valider ou au contraire de modifier l’architecture logicielle imaginée. Il est donc important de faire intervenir cette phase peu après le démarrage de la phase d’architecture.

Sans être nécessaire, et en fonction de la taille du projet, un développeur front (spécialisé sur les technologies d’affichages de l’information) pourra alors livrer une maquette HTML fonctionnelle associée à des planches de styles (ensemble d’éléments unitaire du design: boutons, menus, etc.). Cette maquette sera fournit aux développeurs qui pourront alors commencer d’autant plus vite la phase de développement à proprement parler.

Conclusion

Faites attention à ne pas sur-architecturer un logiciel, ne faites que le strict minimum et le plus simplement possible. Les spécifications d’architecture pouvant se limiter à un document texte associé à 5-6 diagrammes, adaptez le niveau de détail à la taille du projet.

Avec la clôture de la phase avant-projet, le travail de l’architecte ne fait que commencer. Il doit continuer à accompagner l’équipe logiciel pendant tout le cycle de développement du logiciel.

Enfin, il s’agit d’un domaine souvent réservé à des profils spécialisés disposant d’un important background en développement. Et plus important encore, d’une réelle facilité à manipuler des concepts.

Dans la prochaine partie, nous allons nous intéresser aux outils utilisés pour mettre en place la pratique du design émergent, et les écueils à éviter.

Architecture logicielle

Concepts de l’architecture logicielle : introduction

Cette série d’articles se concentre sur les notions et concepts de l’architecture logicielle. Vous n’y trouverez donc pas d’éléments techniques.

Avant d’entrer dans le vif du sujet, je tiens à préciser que l’architecture ne doit pas être vue comme une discipline exécutée par quelques personnes spécialisées. Elle doit être intégrée dans le travail de tout développeur.

du “Big Design Up Front” à l’architecture émergente

Dans la pratique de l’architecture logicielle, historiquement l’architecture à été un travail pensé en phase d’avant projet. Cependant, depuis quelques années, les méthodes agiles cherchent à modifier cet ordre des choses et ont mis au point des pratiques d’architectures au fil de l’eau.

C’est pourquoi les pratiques d’architecture avant projet venant des méthodes de projet en V ou en cascade (nommées “Big Design Up Front” — BDUF) et les architectures émergentes (venant des méthodologies agiles : XP, Scrum, etc.) sont opposées dans leur approche. Plus d’information sur les méthodes de gestion de projet informatique sur la fiche wikipedia dédiée.

Big Design Up Front

Cette pratique consiste à penser l’architecture du logiciel avant la phase de développement. Souvent réalisée par des personnes dédiées, l’architecture se retrouve déconnectée de la phase développement.

La phase d’architecture étant en amont, elle nécessite que les besoins fonctionnels soient figés, ce qui est rarement le cas au début du projet. L’adaptation au changement de l’architecture est quasi-nulle cela peut entraîner des problèmes importants en cas de mauvaise conception initiale.

Les erreurs d’appréciation sont fréquentes. C’est la raison pour laquelle, cette pratique a tendance à créer des architectures beaucoup plus complexes que nécessaire. Et la grande quantité de documentations générée par ce type d’architecture peut créer un faux sentiment de contrôle sur la solution alors même que des éléments importants peuvent être oubliés.

De plus, les architectes peuvent finir par être déconnectés du terrain, créant un phénomène de tour d’ivoire accentuant encore les problématiques déjà citées. Pire, un sentiment de dévalorisation peut apparaître auprès des développeurs qui se retrouvent alors en simple position d’exécutant.

Cependant, il ne faudrait pas croire qu’une phase d’architecture en amont de la production logicielle ne soit pas nécessaire. Mais cette phase doit être limitée à la création d’une vision technique pour le produit, sans aller dans les détails de l’implémentation. Nous parlons dans ce cas d’un “just enough” (juste assez) up front design, notion sur laquelle nous reviendrons un prochain article.

Les systèmes complexes sont un type de projet nécessitant une phase d’architecture en amont. Celle-ci sera plus souvent confié à un architecte en système d’information qui découpera le projet en un ensemble inter-connecté de composants simple. Ces différents composants pourront alors être développé selon les pratiques de “l’emergent design”.

Un autre cas particulier est à prendre en compte pour l’utilisation de cette méthodologie : la reprise de système existant. Dans ce cas de figure, une phase d’architecture en amont est indispensable pour cartographier le code source actuel et préparer les futurs développements.

L’architecture émergente (ou “emergent design”)

Les architectures émergentes se construisent tout au long de la phase de développement. Utilisées massivement par les méthodes agiles, c’est une pratique qui offre beaucoup d’avantage à la condition d’une grande rigueur dans sa mise en œuvre (au niveau des tests notamment).

Le principe de ce type d’architecture est assez simple : les développeurs écrivent un module A, puis un module B. À la fin de la création du module B ils vont chercher les éléments communs à A et B et les factoriser au cours d’une phase dite de “refactorisation”. Ce processus est répété tout au long de la création du logiciel. L’architecture va donc apparaître au fur et à mesure de l’avancée du projet.

Dans ce cas, l’architecture est confiée au soin des développeurs, il faudra donc faire attention à avoir une équipe solide techniquement pour limiter les erreurs nuisant à la maintenabilité future du logicielle. Pour éviter ce type de problèmes, une solution est de mettre en place une équipe de coachs inter-projets qui aideront les équipes dans les phases complexes de la création du logiciel.

Attention, pour éviter des régressions importantes lors des nombreuses phases de refactorisation, il est indispensable de tester unitairement le code source. Dans ce cadre, la mise en place de méthodes orientées sur les tests (ex : “test driven developpement”, consistant à écrire les tests avant le code) doivent être généralisée. Un manquement à cette pratique à un effet délétère sur le code source qui devient in-maintenable.

Les avantages apportés par ces pratiques sont nombreux, sans vouloir être exhaustif nous pouvons citer :

  • Le changement est le bienvenue, en effet l’architecture se construit avec le logiciel. Un changement dans le logiciel n’aura donc qu’un impact très limité sur le logiciel.
  • Le code est souvent plus concis, les développeurs ne développant que ce dont ils ont effectivement besoin, sans créer inutilement des abstractions finalement non utilisées.

Conclusions de cette première partie

Architecturer un logiciel en dehors du cycle de développement est une pratique déconseillée dans la majorité des cas. Une vision technique doit effectivement être mise en place avant que les développements ne démarrent, mais elle doit être limité au strict minimum (just enough up front design). Il est ensuite conseillé de laisser les développeurs définirent eux même la mise en œuvre. À la condition de veiller à introduire des processus de développements rigoureux au niveau des tests, et obliger un travail régulier de refactorisation. Pour aider les développeurs dans ce travail, une équipe inter-projet de “coach” en architecture logicielle pourra être créée pour aider sur les phases sensibles de la conception du logiciel.

Nous verrons dans la suite de cet article quels sont les concepts intellectuels et philosophiques qui sont utilisés pour une bonne architecture logicielle, ainsi que les outils utilisés lors de ces différentes étapes. Enfin nous regarderons comment gérer le cas de la réutilisation de composants logiciels avec ce type d’approche.

image issue de ModeMachine