jeudi 20 novembre 2014

Application N-Tiers et Frameworks

Voyons un peu ce que certains framworks, que l'on peut qualifier de standard apportent à l'architecture N-Tiers.


     IOC : Springframwork, Guice
THE framework, limite on ne peut plus s'en passer, il permet beaucoup de choses et surtout d'intégrer et configurer d'autres frameworks... bref c'est souvent la pierre angulaire du projet. Mais c'est tout simplement un framework IoC ou d'injection de dépendances. Il permet de mieux découpler les couches.  Ainsi on code avec les interfaces et c'est Spring qui se chargera (par la configuration ou les annotations) d'injecter l'implémentation. Point de factory, de singleton à implémenter soi-même.
Il n'a pas d'impact sur le nombre de couches mais il apporte une méthode élégante pour réaliser le couplage faible (par interface) entre les couches.

JEE permet aussi de réaliser l'injection avec une facilité équivalente (annotations)

Coté .NET on trouve des frameworks équivalents mais peut-être pas aussi bien aboutis avec le ServiceLocator et/ou les frameworks Unity, SimpleIOC et Castle. Encore que springframework.net semble palier à cela (promis prochain projet .net je le tente).

     ORM : JPA, Hibernate, Entity Framework 
Aujourd'hui les ORMs sont matures et permettent de masquer l'accès aux bases de données. Là on voit deux méthodes : ceux qui tiennent à la couche de DAO traditionnelle, cette dernière est alors triviale pour tout ce qui est CRUD, mais elle permettra d'isoler le code spécifique pour réaliser des fonctionnalités non prises en charge par l'ORM (rares).
Une approche plus moderne est de faire disparaître cette couche, de s'appuyer directement sur l'ORM depuis la couche métier, et de faire porter le CRUD et les requêtes complexes par le modèle (les classes d'entités de persistance) lui même.
Ainsi si on a une utilisation standard de la persistance dans une base de données relationnelle ou non (certaines base NoSql supportent les standard JPA ou JDO), l'ORM permet de remplacer la couche de DAO et simplifie grandement la structure du projet. C'est ce que l'on voit mis en oeuvre avec les approche de type Rails de Grails par exemple.

    Web Service : CXF (java), WCF (.net)
Les web service sont générés par des framework tiers. De même que les ORM, on peut piloter la mise en forme du message du service par des annotations sur le modèle d'échange (qui peut être ou non celui de persistance). Ce qui réduit l'implémentation d'un service à son strict minimum, seule l'interface est rédigée, l'implémentation est un passe plat qui appelle la couche métier.

     AOP : Spring AOP
L'Aspect Oriented Programing est un paradigme de programmation qui se place au dessus de la programmation orientée objet.
La mise en oeuvre de l'AOP dans une architecture en couche permet d'implémenter des responsabilités transverses aux couches d'architecture ou spécifique à une couche, une classe, une méthode. Bref cette technique est très flexible et elle permet élégamment de mettre en place une fonctionnalité transverse de type :
  • réalisation des logs
  • sécurité
  • gestion de caches
Cela permet de mettre un peu d'huile entre les différentes couche de l'application. En respectant un couplage faible par l'utilisation d'interface, grâce à ces dernières,  l'AOP se met en place avec un moindre coût.

     MVC : Struts, Spring MVC...
Les frameworks MVC our MVVM et autre permettent de réaliser la couche de présentation, mais même si eux même ont un découpage Modèle Vue Contrôleur, ou Modèle Vue VueModel, bref un découpage en 3 catégories il ne faut pas prendre ces dernières comme des couches d'architecture applicative. Peut-être qu'avec un peu de chance le Modèle du MVC correspondra au domaine de l'application. C'est typiquement ce qui arrive dans les architecture Rails ou par convention le domaine est afficher directement, le contrôleur semble être la couche métier et la vue la présentation... mais c'est du Rails. Dans les applications qui ont un peu d'historique et de complexité ce n'est pas le cas, le modèle du MVC est différent du modèle métier de l'application et appartient intégralement à la couche de présentation.

     DOZER :
Cet outil permet de recopier récursivement une grappe d'objet dans une autre grappe par réflexion et en utilisant un fichier de mapping, c'est un outil TRÈS PUISSANT... trop ? J'en parle car je l'ai vu mis en dans le but de découpler les couches logiques d'une application. OK ils disent que c'est un usage possible. Cela ne me semble pas une bonne pratique :
  • surcoût en terme de mémoire et CPU
  • maintenance complexe du code : une propriété doit être ajoutée à plusieurs classes et si son nom change un mapping spécifique dozer doit-être mis en place et testé.
Bref il ne faut mettre un tel outil que s'il apporte une valeur ajoutée importante sur un projet et dans le cadre d'une architecture en couche logique, je ne vois pas sa valeur ajoutée. Sauf dans des cas particuliers, avec un historique lourd... et alors c'est le dernier espoir...  

lundi 27 octobre 2014

Quelles sont les pièges de l'architecture en couches logiques ?

1) le nombre

Comme je le disais c'est d'en faire trop, il en faut juste ce qu'il faut et c'est toujours un peu délicat la tentation est grande d'en ajouter. Mais il faut garder en mémoire que c'est un découpage technique et non fonctionnel du projet.

2 ) les fausses couches

Le MVC (modèle vue contrôleur), le MVVM (modèle vue vue-modèle, un truc Mircosoft) et autre font partie d'une seule couche logique, celle de présentation. 

3 ) Le découplage

Les couches doivent être découplées qu'il disait... et comment ça cause ? A grand coups de Reflexion et de Dozer (bon framework souvent mal utilisé), ça va piquer !
Non sérieux, il y  a un couplage, mais un couplage faible, réalisé par interfaces et uniquement descendant (oui il faut éviter un cycle, ça compile pas les dépendances cycliques). 
Le couplage par interface permet, de ne pas être tributaire d'une implémentation unique, on pourra réaliser une nouvelle implémentation d'une couche sans modification des autres à condition de respecter les interfaces. 

4) Le modèle

L'interface c'est bien pour le "verbe" : les méthodes exposées. Mais il faut aussi un modèle, un modèle métier, souvent le reflet de ce qui est persisté. Il véhicule l'information entre les couches, on le retrouve dans les signatures des méthodes des interface. 
Il peut provenir de l'extérieur : XSD, Modèle de données existant... il faut le partager à toutes les couches au travers de son implémentation (plus simple) ou d'interfaces (plus complexe : mise en place de factory et autre... ), si chaque couche implémente son propre modèle la communication va être complexe et couteuse, bref vous aller lorgner rapidement vers Dozer, ça fera moins de code... ça risque d'être  compliqué de conservé un couplage faible (par interface).
On peut considérer le modèle comme un couche accessible par toute les autres (la couche de plus base niveau).

5 ) le passage d'un couche à l'autre 

On a traité une partie dans le point précédent mais encore un piège ce cache, ne pas respecter les couches. Impossible vous me direz, c'est découplé, enfin disons pas trop couplé. Oui mais on peut toujours faire une méthode qui prend une requête SQL en paramètre depuis la couche présentation passée dans une chaine de caractères. Bref ce sont des couche logique, y a toujours moyen de passer à travers et une simple chaine le permet. Sans parler du problème de sécurité que ce genre de pratique que certain de mes proche, certain de mes amis...

6) Les frameworks

Les frameworks apportent beaucoup au développeur, mais il est nécessaire de bien les maitriser pour ne pas se faire envahir par un framework qui alors prendrait la main sur la conception.
Mais il faut aussi voir que bien utilisé ces derniers permette de simplifier la conception et souvent de supprimer une couche !

Voila on a fait le tour... plus on fait simple plus il y a  de chance que cela fonctionne bien.

Et avec des framework ressents ça donne quoi tout ça ? ORM, Spring, JPA, Linq...

Architecture N-Tiers... N-Layers ?

Le n-tiers c'est de la bal, aujourd'hui et depuis plus d'une décennie tout les softwares se targuent d'être conçus en couche, d'être modulaire, fini l'application monolytique qu'ils disaient. 
Chaque couche a une responsabilité bien définie pour apporter aux développements modularités, simplicité, couplage lâche entre couche... Bref la panacée de la conception software... bref c'est dans wikipedea https://en.wikipedia.org/wiki/Multitier_architecture , pas besoin de faire Polytechnique. La version française se concentre à juste titre sur le 3-Tiers.
Mais que vois-je ? Un souci de traduction entre les 2 définitions anglais/français, une petite subtilité c'est glissée dans la définition anglaise une distinction est faite entre Layers (couches logiques) et Tiers (couches physique)... alors que pour les français 3-Tiers c'est 3 couches logiques. Une erreur dans Wikipedia vous me direz ? Et bien non les définitions sont justes, c'est bien l'usage... alors attention à la lecture de documentations en anglais. Mais alors le 3-Tiers à la Française ne correspond pas du tout au 3-tiers à l'anglaise...
Quand à moi je parle bien de couche logique, de toute façon avec le web les couches logiques et les couches physiques ne correspondent plus, en effet dans un application web la couche de présentation est à la fois exécutée coté serveur (JSP, ASPX...) mais aussi coté client en javascript, css...
On a déjà vu, des architectes s'emmelé là dedans, tiens il me maque une couche (oui il est de bon alois d'en avoir au moins 3) y a qu'a dire que la base de données Oracle en est une ? Non ? Cela fera bien dans mon powerpoint... non mais c'est quoi ce délire.
Voila un graphe anglophone standard et on parle bien de Layers...
 


Bref le N-Tiers francophone est une petite incompréhension de l'anglais réadapté et digérée... amusant non ?

Les couches c'est bon mangez en mais gare à l'indigestion !

Dans le monde réel, souvent ça pique un peu, entre les différents furieux et ayatollah de la couche, du découplage, ce n'est pas rare de voir un nombre de couches gargantuesques... 6..7... peut-être plus... sans parler du mécanisme de découplage mis en oeuvre, les portes de l'enfer s'ouvrent en grand. Déjà qu'au delà de 4 ça sent le souffre... oui on parlait du 3-tiers... enfin 3 layers.. je sais plus des couches qu'on disait. 
La mise en œuvre c'est quelque chose, et c'est souvent du grand n'importe quoi. Et le pire c'est qu'avec un bataillon de développeurs ça va marcher... OK quelques problèmes de performances mais on peut toujours se reposer sur la loi de Moore en décalant la date de livraison suffisamment, on les aura les perfs et ça partira en production. Et puis à l'âge du Cloud du cluster la puissance est infinie ! Au pire on attend l'ordinateur quantique et ça roule ! 
Sans compter la maintenance... ou ajouter un champ dans l'interface devient un véritable parcourt du combattant, chaque couche doit être traverser comme une tranchée ennemie sous le feu de la mitraille, spectacle qui laisse perplexe la plupart des clients...
"Vous voulez un champ date... ok je mets en place une équipe commando, ils travaillerons jour et nuit et dans 10 jours vous l'avez !.... Quoi il faut l'initialiser à la date du jour ! J'appelle Chuck Norris lui seul peu ajouter une règle dans la bonne couche, mais comptez 15 jours".  

Le pire c'est que ça a fini par marcher, validant de facto une telle conception et c'est parti pour le projet suivant. Oui le copier-coller étant le design pattern le plus utiliser, reproduire l'erreur est la base.

Ah que je suis médisant... quelle image je donne des architectes... non il ne faut pas généraliser loin de là. C'est qu'on entend souvent parler des projets qui ont des difficultés, voir en échec, et ceux réalisés dans l'état de l'art passe inaperçu. Il y a alors une valorisation de l'équipe qui après un échec sortira le projet dans la douleur, ils seront souvent montrés en exemple et on fera appel à eux pour les projets importants... qui seront à leur tour douloureux. Mais je m'égare.