vendredi 9 mars 2012

Maman, j'arrête les couches!



Oui maintenant je suis grand : j'arrête les couches (logicielles :-)).

Derrière ce titre un peu provocateur, il y a une vraie réflexion de fond. Les architectures en couche, est-ce vraiment utile? En tous cas, mes récentes expériences en terme de développement me font réfléchir. Voici où en est ma réflexion :

Les couches c'est "historique"

L'architecture logicielle est un très vaste sujet qui évolue sans cesse. Les technologies évoluent, les informaticiens évoluent. Il y a même des effets de mode mais qui peut répondre à la question universelle  : C'est quoi "La" bonne architecture? (si quelqu'un connait la réponse, je suis curieux qu'il me l'explique ;-))

Si on prend un peu de recul et que l'on regarde un peu dans le rétroviseur, on peut constater que les architectures logicielles n'arrêtent pas d'évoluer. Après les architectures client/serveur, il y a eu les architectures 3 tiers puis les architectures n-tiers puis les architectures infini-tiers. Après les architectures infini-tiers, comme cela devenait vraiment trop un plat de spaghetti, de nouveaux concepts sont apparus comme "l'urbanisation" et les architectures orientées services qui, en plus de découper une application horizontalement, propose un découpage vertical.

L'urbanisation, ça veut tout dire et rien dire. On peut parler d'urbanisation à différents niveaux, cela peut aller de la façon de décrire la manière dont le code d'une application doit être découpé à comment structurer un système d'information, la planète, l'univers... 

Si l'on reste à un niveau applicatif, l'idée derrière l'urbanisation c'est de définir des règles pour contraindre le développement dans le but d'organiser et de rendre réutilisable des services. L'objectif des architectures urbanisées est de pouvoir proposer un ensemble de service métiers réutilisable sans même savoir qui pourra les utiliser. Au final on se rend souvent compte qu'il est très dur de définir un service sans savoir qui va le réutiliser.

Oui j'ai dû développer sur ce type d'application. En tant que développeur, l'avantage (le seul que j'ai trouvé...) c'est de proposer un cadre très stricts de développement qui peut aider sur de très grosses équipes de développement. L'inconvénient, c'est d'oublier de réfléchir (ouch mais c'est dangereux ça! ;-)) à la façon de faire les choses et surtout c'est la lourdeur/lenteur de développement :

Développer un simple service de lecture d'un utilisateur dans un contexte de surarchitecture peut ressembler à ça : 
- développer le code utile dans le Dao.
- développer la méthode dans la couche du dessus en appelant la couche la méthode du DAO...
- développer la méthode dans la couche du dessus en appelant la couche du dessous...
- développer la méthode dans la couche du dessus en appelant la couche du dessous...
- développer la méthode dans la couche du dessus en appelant la couche du dessous...
- développer la méthode dans la couche du dessus en appelant la couche du dessous...
- développer la méthode dans la couche du dessus en appelant la couche du dessous...
- développer la méthode dans la couche du dessus en appelant la couche du dessous...

On est content quand on arrive enfin à l'IHM! Ce qu'on retient en tant que développeur, c'est que ce n'est pas très FUN et que la majorité du temps, toutes les couches intermédiaires sont inutiles...

En général ce type d'approche s'accompagne d'un bon gros dossier d'architecture qui, avant même d'avoir écrit la moindre ligne de code, propose le design global de la solution (à la fois en terme de choix technique mais surtout en terme de découpage logique...).

Oui j'avoue, j'ai aussi déjà fait ce type de dossier...

Le danger de tout ça, c'est la "surarchitecture" : c'est à dire de prévoir des choses qui sont plus complexes que nécessaires, qui entraînent une lourdeur de développement et qui ne serviront à rien.

Et sans couche, comment ça peut marcher?


Ça commence mal, car je vais déjà commencer par vous dire que ce n'est pas vrai, il y en toujours des couches. En revanche je vous propose de n'en garder que 2 : l'IHM et le reste de l'application (mais c'est que ça ressemble au bon vieux client/serveur ça).

Là où je pense qu'on peut faire différemment c'est de, par défaut, ne pas définir de structure ou de règle pour le reste de l'application avant de commencer. Et là certains vont me dire : Mais vous êtes fou! Ho oui :


Mais non, je ne suis pas fou!

Pour ça, je vous propose 2 retours d'expériences de développements applicatifs différents qui vont dans ce sens :

- TDD et KISS.
Le premier retour concerne le développement d'une application basée sur Cassandra (from scratch) que j'ai développé en full TDD (Test Drivent Development) avec un état d'esprit KISS (Keep It Simple and Stupid). C'est une application sur laquelle je n'avais fait que le minimum de choix techniques (mais il en faut un peu quand même) et aucun choix logique (à part un découpage IHM / reste de l'application). Le TDD s'est chargé du reste et a fait émerger le design. C'est très étonnant à vivre. J'avais par exemple refusé initialement de mettre en place le pattern DAO et il est apparu à force de refactoring...

- Play!
Le deuxième retour concerne le développement d'une application que j'ai faite récemment avec Play!. Et là, je me suis pris une belle claque. Play! est un framework web Java fait pour faire du Web, centré sur le design par URL, sur la simplicité et sur l’efficacité. Tout est différent et tout est simple : attribut public, méthode d'accès la BDD dans les entités, un fichier de conf et tout est convention over configuration... J'ai développé l'application en un temps record avec très peu de bug et un code très lisible. Je suis même encore surpris sur le peu de code écrit pour "faire le job". Un dernier point important, c'est le plaisir que l'on prend à développer dans ce type de contexte : C'EST LE PIED. Si l'on se recentre un peu nos fameuses couches, Play! est aussi centré sur le principe du design simple avec grossomodo une couche IHM et le reste de l'application...

Pour Conclure

Je dirais simplement que : 
- Ce n'est pas parce qu'on commence simple et sans couches, qu'on ne pourra pas en créer. Le refactoring est fait pour ça.
- Les architectures simples sans (trop) de couches ne sont pas réservées aux petites applications, bien au contraire.
- Ce n'est pas parce qu'on sait qu'on a à faire à une "grosse" application qu'il faut obligatoirement vouloir tout structurer avant de commencer.
- Il faut être bien outillé pour commencer simple : soit d'un point de vue méthodologique comme de TDD soit par du "framework qui permet de faire simple".
- qu'il ne faut pas non plus mettre les requêtes SQL dans les JSP :-)

Vous aussi, vous êtes grands, vous pouvez arrêter les couches!

2 commentaires:

Anonyme a dit…

ressentre => recentre

Jérémy Sevellec a dit…

merci, elle était belle celle là ;-)